CleanTracks.cxx
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include "CleanTracks.hxx"
00022 #include <iostream>
00023
00024
00025 namespace CLAM {
00026
00027
00028 void CleanTracksConfig::DefaultInit()
00029 {
00030
00031 AddAll();
00032 UpdateData();
00033
00034
00035 SetMaxDropOut(3);
00036 SetMinLength(3);
00037 SetFreqDev(20);
00038 SetSamplingRate(44100);
00039 SetSpecSize(22050);
00040 }
00041
00042 CleanTracks::CleanTracks():mTrajectoryArray(100,100),mSearchTrajectories(mTrajectoryArray)
00043 {
00044 Configure(CleanTracksConfig());
00045 }
00046
00047 CleanTracks::CleanTracks(const CleanTracksConfig &c ):mTrajectoryArray(100,100),mSearchTrajectories(mTrajectoryArray)
00048 {
00049 Configure(c);
00050 }
00051
00052 CleanTracks::~CleanTracks()
00053 {}
00054
00055
00056
00057
00058
00059
00060 bool CleanTracks::ConcreteConfigure(const ProcessingConfig& c)
00061 {
00062
00063 CopyAsConcreteConfig(mConfig, c);
00064
00065 mMaxDropOut = mConfig.GetMaxDropOut();
00066 mMinLength= mConfig.GetMinLength();
00067 mFreqDev= 1.0/mConfig.GetFreqDev();
00068 mSamplingRate= mConfig.GetSamplingRate();
00069 mSpecSize= mConfig.GetSpecSize();
00070 return true;
00071 }
00072
00073
00074
00075
00076
00077
00078
00079
00080 bool CleanTracks::Do(void)
00081 {
00082 CLAM_ASSERT(false,"CleanTracks::Do(): Supervised mode not implemented");
00083 return false;
00084 }
00085
00086 bool CleanTracks::Do(Array<SpectralPeakArray*>& peakArrayArray)
00087 {
00088
00089 LoadTracks(peakArrayArray);
00090 FindContinuations();
00091 JoinContinuations(peakArrayArray);
00092 Clean(peakArrayArray);
00093 UpdateTrackIds(peakArrayArray);
00094 return true;
00095 }
00096
00097 bool CleanTracks::Do(Segment& segment)
00098 {
00099 const int nFrames=segment.GetnFrames();
00100 Array<SpectralPeakArray*> spectralPeakArrayArray;
00101 spectralPeakArrayArray.Resize(nFrames);
00102 for(int i=0;i<nFrames;i++)
00103 {
00104 spectralPeakArrayArray.AddElem(&segment.GetFrame(i).GetSpectralPeakArray());
00105 }
00106 return Do(spectralPeakArrayArray);
00107
00108 }
00109
00110 void CleanTracks::LoadTracks(Array<SpectralPeakArray*>& peakArrayArray)
00111 {
00112 for(int i=0;i<peakArrayArray.Size();i++)
00113 {
00114 for(int z=0;z<peakArrayArray[i]->GetnIndexedPeaks();z++)
00115 {
00116 TTrajectory tmpTrajectory;
00117 tmpTrajectory.id=peakArrayArray[i]->GetIndex(z);
00118 tmpTrajectory.beginPos=i;
00119 tmpTrajectory.initialFreq=tmpTrajectory.finalFreq=peakArrayArray[i]->GetFreq(z);
00120 tmpTrajectory.initialMag=tmpTrajectory.finalMag=peakArrayArray[i]->GetMag(z);
00121 tmpTrajectory.length=1;
00122 tmpTrajectory.continuedAtId=-1;
00123 AddTrajectory(tmpTrajectory);
00124 }
00125 }
00126 }
00127
00128 void CleanTracks::FindContinuations()
00129 {
00130 int firstCandidatable = 0;
00131
00132 for(int i=0; i<mTrajectoryArray.Size(); i++)
00133 {
00134 const TTrajectory & toBeAppended = mTrajectoryArray[i];
00135
00136
00137
00138
00139
00140
00141
00142 bool thereIsCandidate=false;
00143
00144
00145
00146 TData bestFreqDif=mFreqDev * mTrajectoryArray[i].finalFreq ;
00147 int bestCandidate=0;
00148
00149
00150 for(int k=firstCandidatable; k<i; k++)
00151 {
00152 const TTrajectory & candidate = mTrajectoryArray[k];
00153
00154
00155
00156 if (candidate.beginPos>=toBeAppended.beginPos) break;
00157
00158 const TSize dropOut=
00159 toBeAppended.beginPos-
00160 (candidate.beginPos+candidate.length);
00161
00162
00163 if (dropOut<=0) continue;
00164
00165 if (dropOut>mMaxDropOut) continue;
00166
00167
00168 const TData frequencyDistance =
00169 Abs(toBeAppended.initialFreq-candidate.finalFreq);
00170 if (frequencyDistance >= bestFreqDif) continue;
00171
00172 bestFreqDif=frequencyDistance;
00173 bestCandidate=k;
00174 thereIsCandidate=true;
00175 }
00176
00177
00178 if (!thereIsCandidate) continue;
00179
00180 TTrajectory & candidateTrajectory = mTrajectoryArray[bestCandidate];
00181
00182
00183
00184
00185
00186
00187 TSize previousFollowerPosition = candidateTrajectory.continuedAtId;
00188
00189 if (previousFollowerPosition != -1)
00190 {
00191 TTrajectory & previousFollower = mTrajectoryArray[previousFollowerPosition];
00192 const TData frequencyDistance =
00193 Abs(previousFollower.initialFreq-candidateTrajectory.finalFreq);
00194 if (frequencyDistance <= bestFreqDif) continue;
00195 }
00196
00197 candidateTrajectory.continuedAtId=toBeAppended.id;
00198
00199 }
00200 }
00201
00202 void CleanTracks::JoinContinuations(Array<SpectralPeakArray*>& peakArrayArray)
00203 {
00204 for(int i=0;i<mTrajectoryArray.Size();i++)
00205 {
00206
00207 int contAt = mTrajectoryArray[i].continuedAtId;
00208
00209
00210 while(mTrajectoryArray[i].continuedAtId!=-1)
00211 {
00212 contAt=mTrajectoryArray[i].continuedAtId;
00213 InterpolatePeaks(mTrajectoryArray[i], peakArrayArray);
00214 }
00215 }
00216 }
00217
00218
00219 void CleanTracks::Clean(Array<SpectralPeakArray*>& peakArrayArray)
00220 {
00221 for(int i=0;i<peakArrayArray.Size();i++)
00222 {
00223 int nDeleted=0;
00224 for(int z=0;z<peakArrayArray[i]->GetnIndexedPeaks();z++)
00225 {
00226 const int id=peakArrayArray[i]->GetIndex(z-nDeleted);
00227 const int trajectoryPosition=FindTrajectoryPosition(id);
00228
00229 if (trajectoryPosition==-1) continue;
00230 if (mTrajectoryArray[trajectoryPosition].length>=mMinLength) continue;
00231
00232
00233 peakArrayArray[i]->DeleteSpectralPeak(z-nDeleted);
00234 peakArrayArray[i]->SetIsIndexUpToDate(true);
00235 peakArrayArray[i]->DeleteIndex(id);
00236 mTrajectoryArray[trajectoryPosition].length--;
00237 if(mTrajectoryArray[trajectoryPosition].length==0)
00238 mTrajectoryArray.DeleteElem(trajectoryPosition);
00239 nDeleted++;
00240 }
00241 }
00242 }
00243
00244
00245 void CleanTracks::UpdateTrackIds(Array<SpectralPeakArray*>& peakArrayArray)
00246 {
00247 for(int i=0;i<peakArrayArray.Size();i++)
00248 {
00249 for(int z=0;z<peakArrayArray[i]->GetnIndexedPeaks();z++)
00250 {
00251 const int currentTrackid=peakArrayArray[i]->GetIndex(z);
00252 const int newTrackid=FindTrajectoryPosition(currentTrackid);
00253 if(newTrackid!=currentTrackid)
00254 {
00255 peakArrayArray[i]->SetIndex(z,newTrackid);
00256 peakArrayArray[i]->SetIsIndexUpToDate(true);
00257 }
00258 }
00259 }
00260 }
00261
00262
00263 void CleanTracks::AddTrajectory(TTrajectory& trajectory)
00264 {
00265
00266 const int pos = FindTrajectoryPosition(trajectory.id);
00267 if(pos==-1)
00268 {
00269
00270 mTrajectoryArray.AddElem(trajectory);
00271 }
00272 else
00273 {
00274
00275 mTrajectoryArray[pos].length++;
00276 mTrajectoryArray[pos].finalFreq=trajectory.finalFreq;
00277 mTrajectoryArray[pos].finalMag=trajectory.finalMag;
00278 }
00279 }
00280
00281 void CleanTracks::InterpolatePeaks(TTrajectory& fromTrajectory, Array<SpectralPeakArray*>& peakArrayArray)
00282 {
00283 const int newTrajPos=FindTrajectoryPosition(fromTrajectory.continuedAtId);
00284 CLAM_ASSERT(newTrajPos>-1,"CleanTracks::InterpolatePeaks:Negative Index for track");
00285 const TTrajectory & toTrajectory = mTrajectoryArray[newTrajPos];
00286 int gap=toTrajectory.beginPos-(fromTrajectory.beginPos+fromTrajectory.length);
00287 TData freqSlope=(toTrajectory.initialFreq-fromTrajectory.finalFreq)/(gap+1);
00288 TData magSlope=(toTrajectory.initialMag-fromTrajectory.finalMag)/(gap+1);
00289 TData currentFreq=fromTrajectory.finalFreq;
00290 TData currentMag=fromTrajectory.finalMag;
00291 TData currentBinPos;
00292 int currentBinWidth;
00293 TData lastBinPos=0;
00294 int z;
00295 for(z=fromTrajectory.beginPos+fromTrajectory.length;z<toTrajectory.beginPos;z++)
00296 {
00297 currentFreq+=freqSlope;
00298 currentMag+=magSlope;
00299 currentBinPos=2*currentFreq*mSpecSize/mSamplingRate;
00300 currentBinWidth=int(currentBinPos-lastBinPos);
00301 lastBinPos=currentBinPos;
00302 SpectralPeak tmpPeak;
00303 tmpPeak.AddPhase();
00304 tmpPeak.AddBinWidth();
00305 tmpPeak.AddBinPos();
00306 tmpPeak.UpdateData();
00307 tmpPeak.SetFreq(currentFreq);
00308 tmpPeak.SetMag(currentMag);
00309 tmpPeak.SetScale(EScale(EScale::eLog));
00310 tmpPeak.SetBinPos(currentBinPos);
00311 tmpPeak.SetBinWidth(currentBinWidth);
00312 peakArrayArray[z]->AddSpectralPeak(tmpPeak, true, fromTrajectory.id);
00313
00314 }
00315
00316 for(z=toTrajectory.beginPos;z<toTrajectory.beginPos+toTrajectory.length;z++)
00317 {
00318 peakArrayArray[z]->SetIndex(peakArrayArray[z]->GetPositionFromIndex(toTrajectory.id),fromTrajectory.id);
00319 }
00320 fromTrajectory.length+=(gap+toTrajectory.length);
00321 fromTrajectory.continuedAtId=mTrajectoryArray[newTrajPos].continuedAtId;
00322 fromTrajectory.finalFreq=mTrajectoryArray[newTrajPos].finalFreq;
00323 mTrajectoryArray.DeleteElem(newTrajPos);
00324
00325 }
00326
00327 TIndex CleanTracks::FindTrajectoryPosition(TIndex id)
00328 {
00329
00330 if (mTrajectoryArray.Size()==0)
00331 return -1;
00332
00333 if (id == mTrajectoryArray[0].id)
00334 return 0;
00335 if (id == mTrajectoryArray[mTrajectoryArray.Size()-1].id)
00336 return mTrajectoryArray.Size()-1;
00337
00338 TTrajectory tmpTrajectory;
00339 tmpTrajectory.id=id;
00340 TIndex trajectoryPosition = mSearchTrajectories.Find(tmpTrajectory);
00341
00342
00343 if (trajectoryPosition!=-1)
00344 if (mTrajectoryArray[trajectoryPosition].id!=id)
00345 return -1;
00346 return trajectoryPosition;
00347 }
00348
00349 };
00350