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 TIndex bestCandidate=-1;
00220 TData tmpDistance;
00221 distance=-1;
00222 int nPeaks=iPeakArray.GetnPeaks();
00223 DataArray& peakFreqBuffer=iPeakArray.GetFreqBuffer();
00224 TData factor=100./currentPeakFreq;
00225
00226
00227 SearchArray<TData> mySearch(peakFreqBuffer);
00228 TIndex found=mySearch.Find(currentPeakFreq);
00229 if (found==-1) found = 0;
00230 TIndex originalFound = found;
00231 distance = Abs(peakFreqBuffer[found]-currentPeakFreq);
00232
00233 TIndex newFound;
00234 TData nextDistance;
00235 if(originalFound<nPeaks-1)
00236 {
00237 for(newFound=found+1; newFound<nPeaks; newFound++)
00238 {
00239 nextDistance = Abs(peakFreqBuffer[newFound]-currentPeakFreq);
00240 if(nextDistance>distance) break;
00241 distance = nextDistance;
00242 }
00243 found = newFound-1;
00244 }
00245 if(originalFound>0)
00246 {
00247 for(newFound=found-1; newFound>-1; newFound--)
00248 {
00249 nextDistance = Abs(peakFreqBuffer[newFound]-currentPeakFreq);
00250 if(nextDistance>distance) break;
00251 distance = nextDistance;
00252 }
00253 found = newFound + 1;
00254 }
00255 distance *= factor;
00256 return found;
00257 }
00258
00259
00260
00261
00262
00263 bool SinTracking::IsBestCandidate(TData candidateFreq, TData currentFreq) const
00264 {
00265 double nextDistance=Abs(currentFreq-candidateFreq);
00266
00267 int nPeaks=mPreviousPeakArray.GetnPeaks();
00268 DataArray& peakFreqBuffer=mPreviousPeakArray.GetFreqBuffer();
00269 for(int i=0;i<nPeaks;i++)
00270 {
00271 if(Abs(peakFreqBuffer[i]-candidateFreq)<nextDistance) return false;
00272 }
00273 return true;
00274
00275 }
00276
00277
00278
00279
00280
00281 void SinTracking::Match(TIndex trackId, TIndex peakIndex,
00282 const SpectralPeak& currentPeak,
00283 SpectralPeakArray& oPeakArray) const
00284 {
00285 CLAM_ASSERT(peakIndex<oPeakArray.GetnPeaks(),"SinTracking::Match: Not a valid peak Index");
00286 oPeakArray.SetSpectralPeak(peakIndex,currentPeak,trackId);
00287
00288 }
00289
00290
00291
00292
00293
00294 void SinTracking::CheckForNewBornTracks(const SpectralPeakArray& iPeakArray,SpectralPeakArray& oPeakArray) const
00295 {
00296 TIndex nonAssignedPeakIndex=0;
00297 bool notFinished=true;
00298 nonAssignedPeakIndex=GetFirstNonAssignedPeakPos(oPeakArray,nonAssignedPeakIndex);
00299 while(notFinished)
00300 {
00301 if(nonAssignedPeakIndex == -1)
00302 {
00303 notFinished=false;
00304 break;
00305 }
00306 else
00307 {
00308
00309
00310
00311 AddNewTrack(nonAssignedPeakIndex,iPeakArray.GetSpectralPeak(nonAssignedPeakIndex),oPeakArray);
00312 nonAssignedPeakIndex++;
00313 nonAssignedPeakIndex=GetFirstNonAssignedPeakPos(oPeakArray,nonAssignedPeakIndex);
00314 }
00315 }
00316
00317 }
00318
00319
00320
00321
00322
00323 TIndex SinTracking::GetFirstNonAssignedPeakPos(const SpectralPeakArray& oPeakArray, TIndex beginAt=0) const
00324 {
00325 const TIndex nPeaks = oPeakArray.GetnPeaks();
00326 if (beginAt>=nPeaks) return -1;
00327 if (beginAt<0) return -1;
00328
00329 int i=oPeakArray.GetFirstNonValidIndexPosition(beginAt);
00330
00331 if(i==nPeaks) return -1;
00332
00333 return i;
00334 }
00335
00336
00337
00338 void SinTracking::Initialization(const SpectralPeakArray& iPeakArray, SpectralPeakArray& oPeakArray)
00339 {
00340 TSize nPeaks=oPeakArray.GetnPeaks();
00341 for(int i=0; i<nPeaks; i++)
00342 {
00343 AddNewTrack(i, iPeakArray.GetSpectralPeak(i), oPeakArray);
00344 }
00345 mPreviousPeakArray=oPeakArray;
00346 }
00347
00348 void SinTracking::KillAll()
00349 {
00350 for (int i=0;i<mnMaxSines;i++)
00351 {
00352 mGuideArray[i].isDead=true;
00353 }
00354 mnActiveGuides=0;
00355 }
00356
00357 bool SinTracking::DoInharmonic(const SpectralPeakArray& iPeakArray,SpectralPeakArray& oPeakArray)
00358 {
00359 if(iPeakArray.GetnPeaks()<mnMaxSines)
00360 oPeakArray.SetnPeaks(iPeakArray.GetnPeaks());
00361 else
00362 oPeakArray.SetnPeaks(mnMaxSines);
00363
00364 oPeakArray.ResetIndices();
00365 oPeakArray.InitIndices();
00366 oPeakArray.SetScale(EScale(EScale::eLog));
00367
00368 if(!mInitialized)
00369 {
00370 Initialization(iPeakArray, oPeakArray);
00371 mInitialized=true;
00372 return true;
00373 }
00374
00375 oPeakArray.SetIsIndexUpToDate(true);
00376 for(int i=0;i<mPreviousPeakArray.GetnPeaks();i++)
00377 {
00378 Tracking(iPeakArray,oPeakArray,i);
00379 }
00380 CheckForNewBornTracks(iPeakArray,oPeakArray);
00381 mPreviousPeakArray=oPeakArray;
00382
00383
00384
00385
00386 return true;
00387 }
00388
00389
00390
00391 bool SinTracking::DoHarmonic(const SpectralPeakArray& in, SpectralPeakArray& out,TData funFreq)
00392 {
00393 out.SetnPeaks(mnMaxSines);
00394
00395 out.ResetIndices();
00396 out.SetScale(EScale(EScale::eLog));
00397
00398 InitHarmonicTracks(out,funFreq);
00399 out.SetIsIndexUpToDate(true);
00400 HarmonicTracking(in, out, funFreq);
00401 mPreviousPeakArray=out;
00402 return true;
00403
00404 }
00405
00406 void SinTracking::HarmonicTracking(const SpectralPeakArray& in,SpectralPeakArray& out,TData funFreq)
00407 {
00408 TData d;
00409 TIndex pos;
00410
00411 out.SetnPeaks(mnMaxSines);
00412
00413
00414 DataArray& oFreqBuffer=out.GetFreqBuffer();
00415 DataArray& iMagBuffer=in.GetMagBuffer();
00416 DataArray& oMagBuffer=out.GetMagBuffer();
00417 DataArray& iPhaseBuffer=in.GetPhaseBuffer();
00418 DataArray& oPhaseBuffer=out.GetPhaseBuffer();
00419
00420
00421 int i;
00422
00423 TSize nPeaks=mnMaxSines;
00424 i=0;
00425 int n;
00426 for(n=0; n<mnMaxSines;n++)
00427 {
00428 pos=GetCandidate(oFreqBuffer[i],in,d);
00429 if(d<funFreq/2 && pos>-1)
00430 {
00431 if(i==0 || iMagBuffer[pos]!=oMagBuffer[i-1])
00432 {
00433 oMagBuffer[i]=iMagBuffer[pos];
00434 oFreqBuffer[i]=oFreqBuffer[n];
00435 oPhaseBuffer[i]=iPhaseBuffer[pos];
00436 i++;
00437 }
00438 }
00439 }
00440 out.SetnPeaks(i);
00441 }
00442
00443 void SinTracking::InitHarmonicTracks(SpectralPeakArray& peaks, TData funFreq)
00444 {
00445 DataArray& freqBuffer=peaks.GetFreqBuffer();
00446 DataArray& magBuffer=peaks.GetMagBuffer();
00447
00448 int i;
00449
00450 TData currentFreq=funFreq;
00451
00452 for(i=0;i<mnMaxSines;i++)
00453 {
00454 freqBuffer[i]=currentFreq;
00455 magBuffer[i]=-99;
00456 currentFreq+=funFreq;
00457 }
00458 }
00459
00460 }
00461