CLAM-Development  1.4.0
SpectralPeakArray.cxx
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2001-2004 MUSIC TECHNOLOGY GROUP (MTG)
3  * UNIVERSITAT POMPEU FABRA
4  *
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19  *
20  */
21 
22 #include "SpectralPeakArray.hxx"
23 #include "ProcessingDataPlugin.hxx"
24 
25 namespace CLAM{
26 
27 namespace Hidden
28 {
29  static ProcessingDataPlugin::Registrator<SpectralPeakArray> dataRegistrator("lightcoral");
30 }
31 
32 
33 
35 //
36 // SpectralPeakArray
37 //
39 
40 
42 {
43  MandatoryInit();
44  InitFromPrototype(prototype);
45 }
46 
48 {
49  //Initializing minimum set of attributes (mag, freq and scale)
50  AddFreqBuffer();
51  AddMagBuffer();
52  // MRJ: More forgotten donuts here. What am I missing here?
53  // SpectralPeakDetect::CheckOutputType demands all SpectralPeakArrays to comply
54  // with the following dyn attribs
55  AddBinWidthBuffer();
56  AddBinPosBuffer();
57  AddPhaseBuffer();
58  // MRJ: End of SpectralPeakDetect::CheckOutputType attributes requirements. It
59  // seems that someone did an optimization that consisted in not adding these
60  // in SpectralPeakDetect::CheckOutputType... Merlijn?
61  AddScale();
62  AddMinimizeResizes();
63  UpdateData();
64  SetScale(EScale(EScale::eLinear));
65  SetnPeaks(0);
66  SetMinimizeResizes(1);
67  mIsIndexUpToDate=false;
68 }
69 
70 void SpectralPeakArray::InitPeak(SpectralPeak& spectralPeak) const
71 {
72  if (HasMagBuffer())
73  spectralPeak.AddMag();
74  else spectralPeak.RemoveMag();
75  if (HasFreqBuffer())
76  spectralPeak.AddFreq();
77  else spectralPeak.RemoveFreq();
78  if (HasPhaseBuffer())
79  spectralPeak.AddPhase();
80  else spectralPeak.RemovePhase();
81  if (HasBinWidthBuffer())
82  spectralPeak.AddBinWidth();
83  else spectralPeak.RemoveBinWidth();
84  if (HasBinPosBuffer())
85  spectralPeak.AddBinPos();
86  else spectralPeak.RemoveBinPos();
87  spectralPeak.UpdateData();
88  spectralPeak.SetScale(GetScale());
89 }
90 
92 {
93  if (spectralPeak.HasMag())
94  AddMagBuffer();
95  else if (HasMagBuffer())
96  RemoveMagBuffer();
97  if (spectralPeak.HasFreq())
98  AddFreqBuffer();
99  else if (HasFreqBuffer())
100  RemoveFreqBuffer();
101  if (spectralPeak.HasPhase())
102  AddPhaseBuffer();
103  else if (HasPhaseBuffer())
104  RemovePhaseBuffer();
105  if (spectralPeak.HasBinWidth())
106  AddBinWidthBuffer();
107  else if (HasBinWidthBuffer())
108  RemoveBinWidthBuffer();
109  if (spectralPeak.HasBinPos())
110  AddBinPosBuffer();
111  else if (HasBinPosBuffer())
112  RemoveBinPosBuffer();
113  UpdateData();
114 }
115 
116 
118 {
119  if (HasMagBuffer()) spectralPeak.AddMag();
120  else spectralPeak.RemoveMag();
121  if (HasFreqBuffer()) spectralPeak.AddFreq();
122  else spectralPeak.RemoveFreq();
123  if (HasPhaseBuffer()) spectralPeak.AddPhase();
124  else spectralPeak.RemovePhase();
125  if (HasBinWidthBuffer()) spectralPeak.AddBinWidth();
126  else spectralPeak.RemoveBinWidth();
127  if (HasBinPosBuffer()) spectralPeak.AddBinPos();
128  else spectralPeak.RemoveBinPos();
129 
130  spectralPeak.UpdateData();
131 }
132 
134 {
135  if (HasMagBuffer()!=spectralPeak.HasMag())
136  return false;
137  if (HasFreqBuffer()!=spectralPeak.HasFreq())
138  return false;
139  if (HasPhaseBuffer()!=spectralPeak.HasPhase())
140  return false;
141  if (HasBinWidthBuffer()!=spectralPeak.HasBinWidth())
142  return false;
143  if (HasBinPosBuffer()!=spectralPeak.HasBinPos())
144  return false;
145  return true;
146 }
147 
148 
150 {
151  return GetSpectralPeak(GetIndexArray()[pos]);
152 }
153 
155 {
156  SpectralPeak tmpPeak;
157  CLAM_ASSERT(pos<GetnPeaks()&&pos>=0,"SpectralPeakArray::GetSpectralPeak:Out of bounds in peak array");
158  InitSpectralPeak(tmpPeak);
159  if (HasMagBuffer())
160  tmpPeak.SetMag(GetMag(pos));
161  if (HasFreqBuffer())
162  tmpPeak.SetFreq(GetFreq(pos));
163  if (HasPhaseBuffer())
164  tmpPeak.SetPhase(GetPhase(pos));
165  if (HasBinWidthBuffer())
166  tmpPeak.SetBinWidth(GetBinWidth(pos));
167  if (HasBinPosBuffer())
168  tmpPeak.SetBinPos(GetBinPos(pos));
169  tmpPeak.SetScale(GetScale());
170 
171  return tmpPeak;
172 }
173 
174 
176 {
177  CLAM_ASSERT(spectralPeak.GetScale()==GetScale(),"SpectralPeakArray::SetSpectralPeak:Incorrect scale in input SpectralPeak");
178  CLAM_ASSERT(pos<GetnPeaks(),"SpectralPeakArray::SetSpectralPeak:Out of bounds in peak array");
179  CLAM_ASSERT(IsCorrectPrototype(spectralPeak),"SpectralPeakArray::SetSpectralPeak:Incorrect prototype for Spectral Peak");
180 
181  if (HasMagBuffer())
182  GetMagBuffer()[pos]=spectralPeak.GetMag();
183  if (HasFreqBuffer())
184  GetFreqBuffer()[pos]=spectralPeak.GetFreq();
185  if (HasPhaseBuffer())
186  GetPhaseBuffer()[pos]=spectralPeak.GetPhase();
187  if (HasBinWidthBuffer())
188  GetBinWidthBuffer()[pos]=spectralPeak.GetBinWidth();
189  if (HasBinPosBuffer())
190  GetBinPosBuffer()[pos]=spectralPeak.GetBinPos();
191  if(HasIndexArray())
192  GetIndexArray()[pos]=index;
193 }
194 
195 void SpectralPeakArray::InsertSpectralPeak(TIndex pos,const SpectralPeak& spectralPeak,bool insertIndex,TIndex index)
196 {
197  CLAM_ASSERT(spectralPeak.GetScale()==GetScale(),"SpectralPeakArray::InsertSpectralPeak:Incorrect scale in input SpectralPeak");
198  CLAM_ASSERT(pos<GetnPeaks(),"SpectralPeakArray::InsertSpectralPeak:Out of bounds in peak array");
199  CLAM_ASSERT(IsCorrectPrototype(spectralPeak),"SpectralPeakArray::InsertSpectralPeak:Incorrect prototype for Spectral Peak");
200  if (HasMagBuffer())
201  GetMagBuffer().InsertElem(pos,spectralPeak.GetMag());
202  if (HasFreqBuffer())
203  GetFreqBuffer().InsertElem(pos,spectralPeak.GetFreq());
204  if (HasPhaseBuffer())
205  GetPhaseBuffer().InsertElem(pos,spectralPeak.GetPhase());
206  if (HasBinWidthBuffer())
207  GetBinWidthBuffer().InsertElem(pos,spectralPeak.GetBinWidth());
208  if (HasBinPosBuffer())
209  GetBinPosBuffer().InsertElem(pos,spectralPeak.GetBinPos());
210  if(insertIndex&&HasIndexArray())
211  GetIndexArray().InsertElem(pos,index);
212 }
213 
214 void SpectralPeakArray::AddSpectralPeak(const SpectralPeak& spectralPeak,bool addIndex,TIndex index)
215 {
216  CLAM_ASSERT(spectralPeak.GetScale()==GetScale(),"SpectralPeakArray::AddSpectralPeak:Incorrect scale in input SpectralPeak");
217  CLAM_ASSERT(IsCorrectPrototype(spectralPeak),"SpectralPeakArray::AddSpectralPeak:Incorrect prototype for Spectral Peak");
218  if (HasMagBuffer())
219  GetMagBuffer().AddElem(spectralPeak.GetMag());
220  if (HasFreqBuffer())
221  GetFreqBuffer().AddElem(spectralPeak.GetFreq());
222  if (HasPhaseBuffer())
223  GetPhaseBuffer().AddElem(spectralPeak.GetPhase());
224  if (HasBinWidthBuffer())
225  GetBinWidthBuffer().AddElem(spectralPeak.GetBinWidth());
226  if (HasBinPosBuffer())
227  GetBinPosBuffer().AddElem(spectralPeak.GetBinPos());
228  if(addIndex&&HasIndexArray())
229  GetIndexArray().AddElem(index);
230 }
231 
233 {
234  CLAM_ASSERT(GetnPeaks()>0&&pos<GetnPeaks(),"SpectralPeakArray::DeleteSpectralPeak:No spectral peak at that position");
235  if (HasMagBuffer())
236  GetMagBuffer().DeleteElem(pos);
237  if (HasFreqBuffer())
238  GetFreqBuffer().DeleteElem(pos);
239  if (HasPhaseBuffer())
240  GetPhaseBuffer().DeleteElem(pos);
241  if (HasBinWidthBuffer())
242  GetBinWidthBuffer().DeleteElem(pos);
243  if (HasBinPosBuffer())
244  GetBinPosBuffer().DeleteElem(pos);
245  if(deleteIndex&&HasIndexArray())
246  GetIndexArray().DeleteElem(pos);
247 }
248 
249 /*Index functionality*/
250 
251 
253 {
254  CLAM_ASSERT(HasIndexArray(),"SpectralPeakArray::GetPositionFromIndex: Index array is not instantiated");
255  CLAM_ASSERT(mIsIndexUpToDate,"SpectralPeakArray::GetPositionFromIndex: Index table is not up to date");
256 
257  //Note: cannot use searching routines because index may not be sorted
258 
259  IndexArray& indexArray=GetIndexArray();
260  for(int i=0;i<indexArray.Size();i++)
261  {
262  if(indexArray[i]==index) return i;//index found
263  }
264  return -1;//index not found
265 
266 }
267 
268 TIndex SpectralPeakArray::GetMaxMagPos() const// returns position of mag maximum
269 {
270  const DataArray & peakMagBuffer=GetMagBuffer();
271  // initialize to the first element
272  double max = peakMagBuffer[0];
273  TIndex maxPos=0;
274  for (TIndex i=1;i<GetnPeaks();i++)
275  {
276  const double & mag = peakMagBuffer[i];
277  if (mag>max)
278  {
279  max = mag;
280  maxPos = i;
281  }
282  }
283  return maxPos;
284 
285 }
286 
287 
288 TIndex SpectralPeakArray::GetMaxMagIndex() const// returns position of mag maximum
289 {
290  const DataArray & peakMagBuffer=GetMagBuffer();
291  // only indexed peaks. It returns the max position
292 
293  CLAM_ASSERT(HasIndexArray(),"SpectralPeakArray::GetMaxMagPosition: Index array is not instantiated");
294  CLAM_ASSERT(mIsIndexUpToDate,"SpectralPeakArray::GetMaxMagPosition: IndexTable is not up to date");
295  const IndexArray & indexArray = GetIndexArray();
296  TIndex maxPos=0;
297  double max = peakMagBuffer[indexArray[0]];
298  // initialize to the first element
299  for (TIndex i=1; i<indexArray.Size(); i++)
300  {
301  const double & mag = peakMagBuffer[indexArray[i]];
302  if (mag>max)
303  {
304  max = mag;
305  maxPos = i;
306  }
307  }
308  return maxPos;
309 
310 }
311 
312 void SpectralPeakArray::ResetIndices() // reset all indices
313 {
314 
315  CLAM_ASSERT(HasIndexArray(),"SpectralPeakArray::ResetIndices: Index array is not instantiated");
316  IndexArray& indexArray=GetIndexArray();
317  TSize nPeaks=GetnPeaks();
318  //Resize will only be done once
319  if(indexArray.AllocatedSize()!=GetnMaxPeaks())
320  indexArray.Resize(GetnMaxPeaks());
321  // set size to the number of Peaks
322  indexArray.SetSize(nPeaks);
323 
324  indexArray.Reset();
325  mIsIndexUpToDate=true;
326 }
327 
328 void SpectralPeakArray::InitIndices() // Initialize all indices to -1 and set size
329 {
330  CLAM_ASSERT(HasIndexArray(),"SpectralPeakArray::InitIndices: Index array is not instantiated");
331  int i;
332  IndexArray& indexArray=GetIndexArray();
333  TSize nPeaks=GetnPeaks();
334  TSize nMaxPeaks=GetnMaxPeaks();
335  indexArray.Resize(nMaxPeaks);
336  indexArray.SetSize(nPeaks);
337  for(i=0;i<nPeaks;i++)
338  {
339  indexArray[i]=-1;
340  }
341  mIsIndexUpToDate=false;
342 }
343 
344 void SpectralPeakArray::SetIndicesTo(TIndex val) // Initialize all indices to -1 without resize
345 { // is upToDate = true !!!
346  CLAM_ASSERT(HasIndexArray(),"SpectralPeakArray::SetIndicesTo: Index array is not instantiated");
347  int i;
348  IndexArray& indexArray=GetIndexArray();
349  TSize nPeaks=GetnPeaks();
350  for(i=0;i<nPeaks;i++)
351  {
352  indexArray[i]=-1;
353  }
354  mIsIndexUpToDate=true;
355 }
356 
357 /* Delete an element from the index array, but not deleting the Peak information */
359 {
360  CLAM_ASSERT(HasIndexArray(),"SpectralPeakArray::DeleteIndex: Index array is not instantiated");
361  TIndex pos = GetPositionFromIndex(index);
362  if (pos>-1)
363  GetIndexArray().DeleteElem(pos);
364 }
365 
367 {
368  CLAM_ASSERT(HasIndexArray(),"SpectralPeakArray::AddIndex: Index array is not instantiated");
369  GetIndexArray().AddElem(index);
370 }
371 
373 {
374  IndexArray& indexArray=GetIndexArray();
375  CLAM_ASSERT(HasIndexArray(),"SpectralPeakArray::GetFirstNonValidIndexPosition: Index array is not instantiated");
376  CLAM_ASSERT(beginAt<indexArray.Size()&&beginAt>=0,"SpectralPeakArray::SetThruIndexFreq: Out of bounds in Index Array");
377  for(int i=beginAt;i<indexArray.Size();i++)
378  {
379  if(indexArray[i]==-1) return i;
380  }
381  return -1;
382 }
383 
385 {
386  int i, nIndexedPeaks=0;
387  IndexArray& indexArray=GetIndexArray();
388  CLAM_ASSERT(HasIndexArray(),"SpectralPeakArray::GetFirstNonValidIndexPosition: Index array is not instantiated");
389  for(i=0;i<indexArray.Size();i++)
390  {
391  if(indexArray[i]!=-1) nIndexedPeaks++;
392  }
393  return nIndexedPeaks;
394 }
395 
396 /* Getters from index */
397 
399 {
400  CLAM_ASSERT(HasIndexArray(),"SpectralPeakArray::GetThruIndexFreq: Index array is not instantiated");
401  CLAM_ASSERT(mIsIndexUpToDate,"SpectralPeakArray::GetThruIndexFreq: IndexTable is not up to date");
402  CLAM_ASSERT(pos<GetIndexArray().Size()&&pos>=0,"SpectralPeakArray::GetThruIndexFreq: Out of bounds in Index Array");
403  return GetFreq(GetIndexArray()[pos]);
404 }
405 
407 {
408  CLAM_ASSERT(HasIndexArray(),"SpectralPeakArray::GetThruIndexMag: Index array is not instantiated");
409  CLAM_ASSERT(mIsIndexUpToDate,"SpectralPeakArray::GetThruIndexMag: IndexTable is not up to date");
410  CLAM_ASSERT(pos<GetIndexArray().Size()&&pos>=0,"SpectralPeakArray::GetThruIndexMag: Out of bounds in Index Array");
411  return GetMag(GetIndexArray()[pos]);
412 }
413 
415 {
416  CLAM_ASSERT(HasIndexArray(),"SpectralPeakArray::GetThruIndexPhase: Index array is not instantiated");
417  CLAM_ASSERT(mIsIndexUpToDate,"SpectralPeakArray::GetThruIndexPhase: IndexTable is not up to date");
418  CLAM_ASSERT(pos<GetIndexArray().Size()&&pos>=0,"SpectralPeakArray::GetThruIndexPhase: Out of bounds in Index Array");
419  return GetPhase(GetIndexArray()[pos]);
420 }
421 
423 {
424  CLAM_ASSERT(HasIndexArray(),"SpectralPeakArray::GetThruIndexBinPos: Index array is not instantiated");
425  CLAM_ASSERT(mIsIndexUpToDate,"SpectralPeakArray::GetThruIndexBinPos: IndexTable is not up to date");
426  CLAM_ASSERT(pos<GetIndexArray().Size()&&pos>=0,"SpectralPeakArray::GetThruIndexBinPos: Out of bounds in Index Array");
427  return GetBinPos(GetIndexArray()[pos]);
428 }
429 
431 {
432  CLAM_ASSERT(HasIndexArray(),"SpectralPeakArray::GetThruIndexBinWidth: Index array is not instantiated");
433  CLAM_ASSERT(mIsIndexUpToDate,"SpectralPeakArray::GetThruIndexBinWidth: IndexTable is not up to date");
434  CLAM_ASSERT(pos<GetIndexArray().Size()&&pos>=0,"SpectralPeakArray::GetThruIndexBinWidth: Out of bounds in Index Array");
435  return GetBinWidth(GetIndexArray()[pos]);
436 }
437 
438 /* Setters from index */
440 {
441  CLAM_ASSERT(HasIndexArray(),"SpectralPeakArray::SetThruIndexSpectralPeak: Index array is not instantiated");
442  CLAM_ASSERT(mIsIndexUpToDate,"SpectralPeakArray::SetThruIndexSpectralPeak: IndexTable is not up to date");
443  CLAM_ASSERT(pos<GetIndexArray().Size()&&pos>=0,"SpectralPeakArray::SetThruIndexSpectralPeak: Out of bounds in Index Array");
444  SetSpectralPeak(GetIndexArray()[pos],peak);
445 }
446 
447 
448 
450 {
451  CLAM_ASSERT(HasIndexArray(),"SpectralPeakArray::SetThruIndexFreq: Index array is not instantiated");
452  CLAM_ASSERT(mIsIndexUpToDate,"SpectralPeakArray::SetThruIndexFreq: IndexTable is not up to date");
453  CLAM_ASSERT(pos<GetIndexArray().Size()&&pos>=0,"SpectralPeakArray::SetThruIndexFreq: Out of bounds in Index Array");
454  SetFreq(GetIndexArray()[pos],freq);
455 }
456 
458 {
459  CLAM_ASSERT(HasIndexArray(),"SpectralPeakArray::SetThruIndexMag: Index array is not instantiated");
460  CLAM_ASSERT(mIsIndexUpToDate,"SpectralPeakArray::SetThruIndexMag: IndexTable is not up to date");
461  CLAM_ASSERT(pos<GetIndexArray().Size()&&pos>=0,"SpectralPeakArray::SetThruIndexMag: Out of bounds in Index Array");
462  SetMag(GetIndexArray()[pos],mag);
463 }
464 
466 {
467  CLAM_ASSERT(HasIndexArray(),"SpectralPeakArray::SetThruIndexPhase: Index array is not instantiated");
468  CLAM_ASSERT(mIsIndexUpToDate,"SpectralPeakArray::SetThruIndexPhase: IndexTable is not up to date");
469  CLAM_ASSERT(pos<GetIndexArray().Size()&&pos>=0,"SpectralPeakArray::SetThruIndexPhase: Out of bounds in Index Array");
470  SetPhase(GetIndexArray()[pos],phase);
471 }
472 
474 {
475  CLAM_ASSERT(HasIndexArray(),"SpectralPeakArray::SetThruIndexBinPos: Index array is not instantiated");
476  CLAM_ASSERT(mIsIndexUpToDate,"SpectralPeakArray::SetThruIndexBinPos: IndexTable is not up to date");
477  CLAM_ASSERT(pos<GetIndexArray().Size()&&pos>=0,"SpectralPeakArray::SetThruIndexBinPos: Out of bounds in Index Array");
478  SetBinPos(GetIndexArray()[pos],binPos);
479 }
480 
482 {
483  CLAM_ASSERT(HasIndexArray(),"SpectralPeakArray::SetThruIndexBinWidth: Index array is not instantiated");
484  CLAM_ASSERT(mIsIndexUpToDate,"SpectralPeakArray::SetThruIndexBinWidth: IndexTable is not up to date");
485  CLAM_ASSERT(pos<GetIndexArray().Size()&&pos>=0,"SpectralPeakArray::SetThruIndexBinWidth: Out of bounds in Index Array");
486  SetBinWidth(GetIndexArray()[pos],binWidth);
487 }
488 
490 {
491  if(GetScale()==EScale::eLog) return;
492 
493  DataArray & mag = GetMagBuffer();
494  const int nPeaks=GetnPeaks();
495  for (int i=0; i<nPeaks; i++)
496  {
497  if(mag[i]==0) mag[i]=TData(0.0001);
498  mag[i]= CLAM_20log10(mag[i]);
499  }
500  SetScale(EScale::eLog);
501 }
502 
504 {
505  if(GetScale()==EScale::eLinear) return;
506 
507  DataArray & mag = GetMagBuffer();
508  const int nPeaks=GetnPeaks();
509  for (int i=0; i<nPeaks; i++)
510  {
511  if(mag[i]==0.0001) mag[i]=0;
512  mag[i]= log2lin(mag[i]);
513  }
514  SetScale(EScale::eLinear);
515 }
516 
517 void SpectralPeakArray::CopyMembers(SpectralPeakArray& sourceSpectralPeakArray)
518 {
519  SetScale( sourceSpectralPeakArray.GetScale() );
520  SetMinimizeResizes( sourceSpectralPeakArray.GetMinimizeResizes() );
521 
522  SetnMaxPeaks(sourceSpectralPeakArray.GetnMaxPeaks());
523  SetnPeaks(sourceSpectralPeakArray.GetnPeaks());
524  ResetIndices();
525 
526  DataArray& srcFreqBuffer = sourceSpectralPeakArray.GetFreqBuffer();
527  DataArray& srcMagBuffer = sourceSpectralPeakArray.GetMagBuffer();
528  DataArray& srcPhaseBuffer = sourceSpectralPeakArray.GetPhaseBuffer();
529  DataArray& srcBinPosBuffer = sourceSpectralPeakArray.GetBinPosBuffer();
530  DataArray& srcBinWidthBuffer = sourceSpectralPeakArray.GetBinWidthBuffer();
531  IndexArray& srcIndexArray = sourceSpectralPeakArray.GetIndexArray();
532 
533  DataArray& targetFreqBuffer = GetFreqBuffer();
534  DataArray& targetMagBuffer = GetMagBuffer();
535  DataArray& targetPhaseBuffer = GetPhaseBuffer();
536  DataArray& targetBinPosBuffer = GetBinPosBuffer();
537  DataArray& targetBinWidthBuffer = GetBinWidthBuffer();
538  IndexArray& targetIndexArray = GetIndexArray();
539 
540  int numberOfPeaks = sourceSpectralPeakArray.GetnPeaks();
541  for (int r=0; r < numberOfPeaks;r++)
542  {
543  // get frequency , mag and phase
544  targetFreqBuffer[r] = srcFreqBuffer[r];
545  targetMagBuffer[r] = srcMagBuffer[r];
546  targetPhaseBuffer[r] = srcPhaseBuffer[r];
547  targetBinPosBuffer[r] = srcBinPosBuffer[r];
548  targetBinWidthBuffer[r] = srcBinWidthBuffer[r];
549  targetIndexArray[r] = srcIndexArray[r];
550  }
551 
552 }
553 
554 //xamat: this operator is bound to fail if operands have different attributes, should add checking?
556 {
557  CLAM_ASSERT(in.HasMagBuffer(), "SpectralPeakArray::operator+: second operand needs to have a Magnitude Buffer");
558  CLAM_ASSERT(in.HasFreqBuffer(), "SpectralPeakArray::operator+: second operand needs to have a Frequency Buffer");
559  CLAM_ASSERT(in.HasPhaseBuffer(), "SpectralPeakArray::operator+: second operand needs to have a Phase Buffer");
560  CLAM_ASSERT(in.HasIndexArray(), "SpectralPeakArray::operator+: second operand needs to have an Index Array");
561  CLAM_ASSERT(HasMagBuffer(), "SpectralPeakArray::operator+: first operand needs to have a Magnitude Buffer");
562  CLAM_ASSERT(HasFreqBuffer(), "SpectralPeakArray::operator+: first operand needs to have a Frequency Buffer");
563  CLAM_ASSERT(HasPhaseBuffer(), "SpectralPeakArray::operator+: first operand needs to have a Phase Buffer");
564  CLAM_ASSERT(HasIndexArray(), "SpectralPeakArray::operator+: first operand needs to have an Index Array");
565 
566 
567  SpectralPeakArray tmp;
568  tmp.AddIndexArray();
569  tmp.UpdateData();
570  tmp.SetScale(in.GetScale());
571 
573  tmp.SetnPeaks(tmp.GetnMaxPeaks());
574 
575  int origIndex=0,inIndex=0;
576  DataArray& inPeakMagArray = in.GetMagBuffer();
577  DataArray& inPeakFreqArray = in.GetFreqBuffer();
578  DataArray& inPeakPhaseArray = in.GetPhaseBuffer();
579  IndexArray& inPeakIndexArray = in.GetIndexArray();
580 
581  DataArray& origPeakMagArray = GetMagBuffer();
582  DataArray& origPeakFreqArray = GetFreqBuffer();
583  DataArray& origPeakPhaseArray = GetPhaseBuffer();
584  IndexArray& origPeakIndexArray = GetIndexArray();
585 
586  DataArray& tmpPeakMagArray = tmp.GetMagBuffer();
587  DataArray& tmpPeakFreqArray = tmp.GetFreqBuffer();
588  DataArray& tmpPeakPhaseArray = tmp.GetPhaseBuffer();
589  IndexArray& tmpPeakIndexArray = tmp.GetIndexArray();
590 
591  bool finished=false,finishedOrig=false, finishedIn=false;
592  TSize origSize,inSize;
593  origSize=GetnPeaks();
594  inSize=in.GetnPeaks();
595  //xamat optimizing
596  int nAddedPeaks = 0;
597  while(!finished)
598  {
599  if(origIndex>=origSize-1) finishedOrig=true;
600  if(inIndex>=inSize-1) finishedIn=true;
601  //add always peak with lower freq. If both are equal, add magnitudes (and take original phase?)
602  if(finishedOrig)
603  {
604  if(!finishedIn)
605  {
606  //note: we could overload the SetSpectralPeak operator but not passing a SpectralPeaks but the values
607  tmpPeakMagArray[nAddedPeaks] = inPeakMagArray[inIndex];
608  tmpPeakFreqArray[nAddedPeaks] = inPeakFreqArray[inIndex];
609  tmpPeakPhaseArray[nAddedPeaks] = inPeakMagArray[inIndex];
610  tmpPeakIndexArray[nAddedPeaks] = inPeakIndexArray[inIndex]*2+1;
611 
612  nAddedPeaks++;
613  inIndex++;
614  }
615  else finished=true;
616  }
617  else if(finishedIn)
618  {
619  if(!finishedOrig)
620  {
621  tmpPeakMagArray[nAddedPeaks] = origPeakMagArray[origIndex];
622  tmpPeakFreqArray[nAddedPeaks] = origPeakFreqArray[origIndex];
623  tmpPeakPhaseArray[nAddedPeaks] = origPeakMagArray[origIndex];
624  tmpPeakIndexArray[nAddedPeaks] = origPeakIndexArray[origIndex]*2;
625 
626  nAddedPeaks++;
627  origIndex++;
628  }
629  else finished=true;
630  }
631  else
632  {
633  if(origPeakFreqArray[origIndex]<inPeakFreqArray[inIndex])
634  {
635  tmpPeakMagArray[nAddedPeaks] = origPeakMagArray[origIndex];
636  tmpPeakFreqArray[nAddedPeaks] = origPeakFreqArray[origIndex];
637  tmpPeakPhaseArray[nAddedPeaks] = origPeakMagArray[origIndex];
638  tmpPeakIndexArray[nAddedPeaks] = origPeakIndexArray[origIndex]*2;
639  nAddedPeaks++;
640  origIndex++;
641  }
642  else if(origPeakFreqArray[origIndex]>inPeakFreqArray[inIndex])
643  {
644  tmpPeakMagArray[nAddedPeaks] = inPeakMagArray[inIndex];
645  tmpPeakFreqArray[nAddedPeaks] = inPeakFreqArray[inIndex];
646  tmpPeakPhaseArray[nAddedPeaks] = inPeakMagArray[inIndex];
647  tmpPeakIndexArray[nAddedPeaks] = inPeakIndexArray[inIndex]*2+1;
648 
649  nAddedPeaks++;
650  inIndex++;
651  }
652  else
653  {
654  tmpPeakMagArray[nAddedPeaks] = origPeakMagArray[origIndex];
655  tmpPeakFreqArray[nAddedPeaks] = origPeakFreqArray[origIndex];
656  tmpPeakPhaseArray[nAddedPeaks] = origPeakMagArray[origIndex];
657  tmpPeakIndexArray[nAddedPeaks] = origPeakIndexArray[origIndex]*2;
658 
659  nAddedPeaks++;
660  origIndex++;
661  tmpPeakMagArray[nAddedPeaks] = inPeakMagArray[inIndex];
662  tmpPeakFreqArray[nAddedPeaks] = inPeakFreqArray[inIndex];
663  tmpPeakPhaseArray[nAddedPeaks] = inPeakMagArray[inIndex];
664  tmpPeakIndexArray[nAddedPeaks] = inPeakIndexArray[inIndex]*2+1;
665 
666  nAddedPeaks++;
667  inIndex++;
668  }
669  }
670  }
671  tmp.SetnPeaks(nAddedPeaks);
672  return tmp;
673 }
674 
675 };//namespace
676