38 SetSamplingRate(44100);
65 mMaxDropOut = mConfig.GetMaxDropOut();
66 mMinLength= mConfig.GetMinLength();
67 mFreqDev= 1.0/mConfig.GetFreqDev();
68 mSamplingRate= mConfig.GetSamplingRate();
69 mSpecSize= mConfig.GetSpecSize();
82 CLAM_ASSERT(
false,
"CleanTracks::Do(): Supervised mode not implemented");
89 LoadTracks(peakArrayArray);
91 JoinContinuations(peakArrayArray);
92 Clean(peakArrayArray);
93 UpdateTrackIds(peakArrayArray);
101 spectralPeakArrayArray.
Resize(nFrames);
102 for(
int i=0;i<nFrames;i++)
104 spectralPeakArrayArray.
AddElem(&segment.
GetFrame(i).GetSpectralPeakArray());
106 return Do(spectralPeakArrayArray);
112 for(
int i=0;i<peakArrayArray.
Size();i++)
114 for(
int z=0;z<peakArrayArray[i]->GetnIndexedPeaks();z++)
117 tmpTrajectory.
id=peakArrayArray[i]->GetIndex(z);
123 AddTrajectory(tmpTrajectory);
128 void CleanTracks::FindContinuations()
130 int firstCandidatable = 0;
132 for(
int i=0; i<mTrajectoryArray.
Size(); i++)
134 const TTrajectory & toBeAppended = mTrajectoryArray[i];
142 bool thereIsCandidate=
false;
146 TData bestFreqDif=mFreqDev * mTrajectoryArray[i].finalFreq ;
150 for(
int k=firstCandidatable; k<i; k++)
152 const TTrajectory & candidate = mTrajectoryArray[k];
156 if (candidate.beginPos>=toBeAppended.beginPos)
break;
159 toBeAppended.beginPos-
160 (candidate.beginPos+candidate.length);
163 if (dropOut<=0)
continue;
165 if (dropOut>mMaxDropOut)
continue;
168 const TData frequencyDistance =
169 Abs(toBeAppended.initialFreq-candidate.finalFreq);
170 if (frequencyDistance >= bestFreqDif)
continue;
172 bestFreqDif=frequencyDistance;
174 thereIsCandidate=
true;
178 if (!thereIsCandidate)
continue;
180 TTrajectory & candidateTrajectory = mTrajectoryArray[bestCandidate];
187 TSize previousFollowerPosition = candidateTrajectory.continuedAtId;
189 if (previousFollowerPosition != -1)
191 TTrajectory & previousFollower = mTrajectoryArray[previousFollowerPosition];
192 const TData frequencyDistance =
193 Abs(previousFollower.initialFreq-candidateTrajectory.finalFreq);
194 if (frequencyDistance <= bestFreqDif)
continue;
197 candidateTrajectory.continuedAtId=toBeAppended.id;
202 void CleanTracks::JoinContinuations(Array<SpectralPeakArray*>& peakArrayArray)
204 for(
int i=0;i<mTrajectoryArray.
Size();i++)
207 int contAt = mTrajectoryArray[i].continuedAtId;
210 while(mTrajectoryArray[i].continuedAtId!=-1)
212 contAt=mTrajectoryArray[i].continuedAtId;
213 InterpolatePeaks(mTrajectoryArray[i], peakArrayArray);
219 void CleanTracks::Clean(Array<SpectralPeakArray*>& peakArrayArray)
221 for(
int i=0;i<peakArrayArray.Size();i++)
224 for(
int z=0;z<peakArrayArray[i]->GetnIndexedPeaks();z++)
226 const int id=peakArrayArray[i]->GetIndex(z-nDeleted);
227 const int trajectoryPosition=FindTrajectoryPosition(
id);
229 if (trajectoryPosition==-1)
continue;
230 if (mTrajectoryArray[trajectoryPosition].length>=mMinLength)
continue;
233 peakArrayArray[i]->DeleteSpectralPeak(z-nDeleted);
234 peakArrayArray[i]->SetIsIndexUpToDate(
true);
235 peakArrayArray[i]->DeleteIndex(
id);
236 mTrajectoryArray[trajectoryPosition].length--;
237 if(mTrajectoryArray[trajectoryPosition].length==0)
238 mTrajectoryArray.
DeleteElem(trajectoryPosition);
245 void CleanTracks::UpdateTrackIds(Array<SpectralPeakArray*>& peakArrayArray)
247 for(
int i=0;i<peakArrayArray.Size();i++)
249 for(
int z=0;z<peakArrayArray[i]->GetnIndexedPeaks();z++)
251 const int currentTrackid=peakArrayArray[i]->GetIndex(z);
252 const int newTrackid=FindTrajectoryPosition(currentTrackid);
253 if(newTrackid!=currentTrackid)
255 peakArrayArray[i]->SetIndex(z,newTrackid);
256 peakArrayArray[i]->SetIsIndexUpToDate(
true);
263 void CleanTracks::AddTrajectory(
TTrajectory& trajectory)
266 const int pos = FindTrajectoryPosition(trajectory.id);
270 mTrajectoryArray.
AddElem(trajectory);
275 mTrajectoryArray[pos].length++;
276 mTrajectoryArray[pos].finalFreq=trajectory.finalFreq;
277 mTrajectoryArray[pos].finalMag=trajectory.finalMag;
281 void CleanTracks::InterpolatePeaks(
TTrajectory& fromTrajectory, Array<SpectralPeakArray*>& peakArrayArray)
283 const int newTrajPos=FindTrajectoryPosition(fromTrajectory.continuedAtId);
284 CLAM_ASSERT(newTrajPos>-1,
"CleanTracks::InterpolatePeaks:Negative Index for track");
285 const TTrajectory & toTrajectory = mTrajectoryArray[newTrajPos];
286 int gap=toTrajectory.beginPos-(fromTrajectory.beginPos+fromTrajectory.length);
287 TData freqSlope=(toTrajectory.initialFreq-fromTrajectory.finalFreq)/(gap+1);
288 TData magSlope=(toTrajectory.initialMag-fromTrajectory.finalMag)/(gap+1);
289 TData currentFreq=fromTrajectory.finalFreq;
290 TData currentMag=fromTrajectory.finalMag;
295 for(z=fromTrajectory.beginPos+fromTrajectory.length;z<toTrajectory.beginPos;z++)
297 currentFreq+=freqSlope;
298 currentMag+=magSlope;
299 currentBinPos=2*currentFreq*mSpecSize/mSamplingRate;
300 currentBinWidth=
int(currentBinPos-lastBinPos);
301 lastBinPos=currentBinPos;
302 SpectralPeak tmpPeak;
304 tmpPeak.AddBinWidth();
306 tmpPeak.UpdateData();
307 tmpPeak.SetFreq(currentFreq);
308 tmpPeak.SetMag(currentMag);
310 tmpPeak.SetBinPos(currentBinPos);
311 tmpPeak.SetBinWidth(currentBinWidth);
312 peakArrayArray[z]->AddSpectralPeak(tmpPeak,
true, fromTrajectory.id);
316 for(z=toTrajectory.beginPos;z<toTrajectory.beginPos+toTrajectory.length;z++)
318 peakArrayArray[z]->SetIndex(peakArrayArray[z]->GetPositionFromIndex(toTrajectory.id),fromTrajectory.id);
320 fromTrajectory.length+=(gap+toTrajectory.length);
321 fromTrajectory.continuedAtId=mTrajectoryArray[newTrajPos].continuedAtId;
322 fromTrajectory.finalFreq=mTrajectoryArray[newTrajPos].finalFreq;
330 if (mTrajectoryArray.
Size()==0)
333 if (
id == mTrajectoryArray[0].
id)
335 if (
id == mTrajectoryArray[mTrajectoryArray.
Size()-1].id)
336 return mTrajectoryArray.
Size()-1;
340 TIndex trajectoryPosition = mSearchTrajectories.
Find(tmpTrajectory);
343 if (trajectoryPosition!=-1)
344 if (mTrajectoryArray[trajectoryPosition].
id!=
id)
346 return trajectoryPosition;