CLAM-Development  1.4.0
SpectrumAdder2.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 "Complex.hxx"
23 #include "SpecTypeFlags.hxx"
24 #include "SpectrumAdder2.hxx"
25 #include "BPF.hxx"
26 #include "Point.hxx"
27 
28 namespace CLAM {
29 
31  : mSize(0),
32  mIn1("Input 1",this),
33  mIn2("Input 2",this),
34  mOut("Output",this),
35  mProtoState(SOther)
36  {
38  }
39 
41  : mSize(0),
42  mIn1("Input 1",this),
43  mIn2("Input 2",this),
44  mOut("Output",this),
45  mProtoState(SOther)
46  {
47  Configure(c);
48  }
49 
50  std::string SpectrumAdder2::NewUniqueName()
51  {
52  static int ObjectCount=0;
53 
54  std::stringstream name;
55  name << "SpectrumAdder2_" << ObjectCount++;
56 
57  return name.str();
58  }
59 
60  bool SpectrumAdder2::ConcreteConfigure(const ProcessingConfig&c)
61  {
62  // Nothing specific to configure here...
63  CopyAsConcreteConfig(mConfig, c);
64 
65  return true;
66  }
67 
68  // Unsupervised Do() function.
70  {
72  "SpectrumAdder2::Do(): Not in execution mode");
73 
74  switch (mProtoState) {
75  // Fast prototype configurations
76  case SMagPhase:
77  AddMagPhase(in1,in2,out);
78  break;
79  case SComplex:
80  AddComplex(in1,in2,out);
81  break;
82  case SPolar:
83  AddPolar(in1,in2,out);
84  break;
85  case SBPF:
86  AddBPF(in1,in2,out);
87  break;
88  case SBPFMagPhase:
89  AddBPFMagPhase(in1,in2,out);
90  break;
91  case SBPFComplex:
92  AddBPFComplex(in1,in2,out);
93  break;
94  case SBPFPolar:
95  AddBPFPolar(in1,in2,out);
96  break;
97  case SMagPhaseBPF:
98  AddMagPhaseBPF(in1,in2,out);
99  break;
100  case SComplexBPF:
101  AddComplexBPF(in1,in2,out);
102  break;
103  case SPolarBPF:
104  AddPolarBPF(in1,in2,out);
105  break;
106  // Slow type configurations
107  case SOther:
108  Add(in1,in2,out);
109  break;
110  default:
111  CLAM_ASSERT(false,"Do(...) : internal inconsistency (invalid mProtoState)");
112  }
113 
114  return true;
115  }
116 
118  {
119  bool result = Do( mIn1.GetData(), mIn2.GetData(), mOut.GetData() );
120  mIn1.Consume();
121  mIn2.Consume();
122  mOut.Produce();
123  return result;
124  }
125 
126  // This function analyses the inputs and decides which prototypes to use
127  // For the sum computation.
128  bool SpectrumAdder2::SetPrototypes(const Spectrum& in1,const Spectrum& in2,const Spectrum& out)
129  {
130  // Check common attributes
131  SpecTypeFlags t1;
132  in1.GetType(t1);
133  SpecTypeFlags t2;
134  in2.GetType(t2);
135  SpecTypeFlags to;
136  out.GetType(to);
137 
138  // Sanity check:
139  CLAM_ASSERT(t1.bMagPhase || t1.bComplex || t1.bPolar || t1.bMagPhaseBPF, "SpectrumAdder2: Spectrum object with no attributes");
140  CLAM_ASSERT(t2.bMagPhase || t2.bComplex || t2.bPolar || t2.bMagPhaseBPF, "SpectrumAdder2: Spectrum object with no attributes");
141  CLAM_ASSERT(to.bMagPhase || to.bComplex || to.bPolar || to.bMagPhaseBPF, "SpectrumAdder2: Spectrum object with no attributes");
142 
143  // Adder size. "pure" BPFs are not considered here.
144  mSize = 0;
145  if (t1.bMagPhase || t1.bComplex || t1.bPolar) {
146  mSize = in1.GetSize();
147  CLAM_ASSERT(mSize,"SpectrumAdder2::SetPrototypes: Zero size spectrum");
148  }
149  if (t2.bMagPhase || t2.bComplex || t2.bPolar) {
150  if (mSize) {
151  CLAM_ASSERT(mSize == in2.GetSize(),"SpectrumAdder2::SetPrototypes:Size mismatch in spectrum sum");
152  }
153  else {
154  mSize = in2.GetSize();
155  CLAM_ASSERT(mSize,"SpectrumAdder2::SetPrototypes: Zero size spectrum");
156  }
157  }
158  if (to.bMagPhase || to.bComplex || to.bPolar) {
159  if (mSize) {
160  CLAM_ASSERT(mSize == out.GetSize(),"SpectrumAdder2::SetPrototypes:Size mismatch in spectrum sum");
161  }
162  else {
163  mSize = out.GetSize();
164  CLAM_ASSERT(mSize,"SpectrumAdder2::SetPrototypes: Zero size spectrum");
165  }
166  }
167 
168  // Spectral Range.
169  // We could also ignore BPF-only objects here, but in
170  // practice, if a BPF is designed for a certain spectral
171  // range, error will probably be too big out of the range, out
172  // we always force range matching
173  CLAM_ASSERT(in1.GetSpectralRange() == in2.GetSpectralRange() &&
174  in1.GetSpectralRange() == out.GetSpectralRange() ,"SpectrumAdder2::SetPrototypes: Spectral range mismatch in spectrum sum");
175 
176  // Scale.
177  if (in1.GetScale() == EScale::eLinear) {
178  if (in2.GetScale() == EScale::eLinear)
179  mScaleState=Slinlin;
180  else
181  mScaleState=Slinlog;
182  }
183  else {
184  if (in2.GetScale() == EScale::eLinear)
185  mScaleState=Sloglin;
186  else
187  mScaleState=Sloglog;
188  }
189  // Log scale output might be useful, for example when working
190  // with BPF objects at the three ports. But right for now...
191  CLAM_ASSERT(out.GetScale() != EScale::eLog,"SpectrumAdder2: Log Scale Output not implemented");
192 
193  // Prototypes.
194 
195  // BPF SUMS.
196  bool i1BPF=false, i2BPF=false, oBPF=false;
197  if (t1.bMagPhaseBPF && !t1.bComplex && !t1.bPolar && !t1.bMagPhase)
198  i1BPF=true;
199  if (t2.bMagPhaseBPF && !t2.bComplex && !t2.bPolar && !t2.bMagPhase)
200  i2BPF=true;
201  if (to.bMagPhaseBPF && !to.bComplex && !to.bPolar && !to.bMagPhase)
202  oBPF=true;
203 
204  if (oBPF) {
205  // BPF output requires interpolating the inputs.
206  mProtoState=SBPF;
207  return true;
208  }
209  if (i1BPF) {
210  // States with direct BPF implementation.
211  if (t2.bMagPhase && to.bMagPhase) {
212  mProtoState=SBPFMagPhase;
213  return true;
214  }
215  if (t2.bComplex && to.bComplex) {
216  mProtoState=SBPFComplex;
217  return true;
218  }
219  if (t2.bPolar && to.bPolar) {
220  mProtoState=SBPFPolar;
221  return true;
222  }
223  // States requiring 1 conversion:
224  if (t2.bMagPhase || to.bMagPhase) {
225  mProtoState=SBPFMagPhase;
226  return true;
227  }
228  if (t2.bComplex || to.bComplex) {
229  mProtoState=SBPFComplex;
230  return true;
231  }
232  if (t2.bPolar || to.bPolar) {
233  mProtoState=SBPFPolar;
234  return true;
235  }
236  // Should never get here:
237  CLAM_ASSERT(false, "SpectrumAdder2::SetPrototypes: Data flags internal inconsistency");
238  }
239  if (i2BPF) {
240  // States with direct BPF implementation.
241  if (t1.bMagPhase && to.bMagPhase) {
242  mProtoState=SMagPhaseBPF;
243  return true;
244  }
245  if (t1.bComplex && to.bComplex) {
246  mProtoState=SComplexBPF;
247  return true;
248  }
249  if (t1.bPolar && to.bPolar) {
250  mProtoState=SPolarBPF;
251  return true;
252  }
253  // States requiring 1 conversion:
254  if (t1.bMagPhase || to.bMagPhase) {
255  mProtoState=SMagPhaseBPF;
256  return true;
257  }
258  if (t1.bComplex || to.bComplex) {
259  mProtoState=SComplexBPF;
260  return true;
261  }
262  if (t1.bPolar || to.bPolar) {
263  mProtoState=SPolarBPF;
264  return true;
265  }
266  CLAM_ASSERT(false, "SpectrumAdder2::SetPrototypes: invalid data flags");
267  }
268  // Direct non-BPF states.
269  if (t1.bMagPhase && t2.bMagPhase && to.bMagPhase) {
270  mProtoState=SMagPhase;
271  return true;
272  }
273  if (t1.bComplex && t2.bComplex && to.bComplex) {
274  mProtoState=SComplex;
275  return true;
276  }
277  if (t1.bPolar && t2.bPolar && to.bPolar) {
278  mProtoState=SPolar;
279  return true;
280  }
281  // States Requiring 1 Conversion
282  if ( (t1.bMagPhase && t2.bMagPhase) ||
283  (t1.bMagPhase && to.bMagPhase) ||
284  (t2.bMagPhase && to.bMagPhase)) {
285  mProtoState=SMagPhase;
286  return true;
287  }
288  if ( (t1.bComplex && t2.bComplex) ||
289  (t1.bComplex && to.bComplex) ||
290  (t2.bComplex && to.bComplex)) {
291  mProtoState=SComplex;
292  return true;
293  }
294  if ( (t1.bPolar && t2.bPolar) ||
295  (t1.bPolar && to.bPolar) ||
296  (t2.bPolar && to.bPolar)) {
297  mProtoState=SPolar;
298  return true;
299  }
300  // Bad luck. We require 2 conversions...
301  mProtoState=SMagPhase;
302  return true;
303  }
304 
305 
307  {
308  CLAM_ASSERT(false, "SetPrototypes not implemented ");
309  return false;
310  }
311 
313  {
314  mProtoState=SOther;
315  return true;
316  }
317 
318 
319  void SpectrumAdder2::Add(Spectrum& in1, Spectrum& in2, Spectrum& out)
320  {
321  PrototypeState state_copy = mProtoState;
322  ScaleState state2_copy = mScaleState;
323 
324  SetPrototypes(in1,in2,out);
325  Do(in1,in2,out);
326 
327  mProtoState = state_copy;
328  mScaleState = state2_copy;
329  }
330 
331 
332  void SpectrumAdder2::AddMagPhase(Spectrum& in1, Spectrum& in2, Spectrum& out)
333  {
334  switch(mScaleState) {
335  case Slinlin:
336  AddMagPhaseLin(in1,in2,out);
337  break;
338  case Sloglog:
339  AddMagPhaseLog(in1,in2,out);
340  break;
341  case Slinlog:
342  AddMagPhaseLinLog(in1,in2,out);
343  break;
344  case Sloglin:
345  AddMagPhaseLinLog(in2,in1,out);
346  break;
347  }
348  }
349 
350  void SpectrumAdder2::AddMagPhaseLin(Spectrum& in1, Spectrum& in2, Spectrum& out)
351  {
352  bool remove1=false,remove2=false,remove3=false;
353  SpecTypeFlags f;
354 
355  // This function was choosed because outme of the data objects had
356  // their MagPhase attribute instantiated. We don't know which of
357  // them, though, out we must check and instantiate the attribute
358  // it it is missed. This could be optimised out by adding more
359  // States, see coments on this in the class declaration.
360  in1.GetType(f);
361  if (!f.bMagPhase) {
362  remove1=true;
363  f.bMagPhase=true;
364  in1.SetTypeSynchronize(f);
365  }
366  in2.GetType(f);
367  if (!f.bMagPhase) {
368  remove2=true;
369  f.bMagPhase=true;
370  in2.SetTypeSynchronize(f);
371  }
372  out.GetType(f);
373  if (!f.bMagPhase) {
374  remove3=true;
375  f.bMagPhase=true;
376  out.SetType(f);
377  }
378 
379  TData *m1 = in1.GetMagBuffer().GetPtr();
380  TData *f1 = in1.GetPhaseBuffer().GetPtr();
381  TData *m2 = in2.GetMagBuffer().GetPtr();
382  TData *f2 = in2.GetPhaseBuffer().GetPtr();
383  TData *mo = out.GetMagBuffer().GetPtr();
384  TData *fo = out.GetPhaseBuffer().GetPtr();
385  for (int i=0;i<mSize;i++) {
386 
387  TData r1,i1,r2,i2,r3,i3;
388 
389  r1 = Abs(m1[i]) * CLAM_cos(f1[i]);
390  i1 = Abs(m1[i]) * CLAM_sin(f1[i]);
391  r2 = Abs(m2[i]) * CLAM_cos(f2[i]);
392  i2 = Abs(m2[i]) * CLAM_sin(f2[i]);
393 
394  r3 = r1+r2;
395  i3 = i1+i2;
396 /*#ifdef CLAM_OPTIMIZE
397  const float insignificant = 0.000001;
398  TData absIm = Abs(i3);
399  TData absRe = Abs(r3);
400  if(absIm<insignificant && absRe>insignificant) mo[i] = absRe;
401  else if(absRe<insignificant && absIm>insignificant) mo[i] = absIm;
402  else mo[i] = CLAM_sqrt (r3*r3 + i3*i3);
403 #else
404 */ mo[i] = CLAM_sqrt (r3*r3 + i3*i3);
405 //#endif
406  fo[i] = CLAM_atan2 (i3,r3);
407 
408  //Polar po=Polar(m1[i],f1[i])+Polar(m2[i],f2[i]);
409  //mo[i]=po.Mag();
410  //fo[i]=po.Ang();
411  }
412 
413 //#ifndef CLAM_OPTIMIZE
414 //if optimizations are on we asume the spectrums do not need to be converted back
415  f.bComplex=f.bPolar=f.bMagPhaseBPF=false;
416  f.bMagPhase=true;
417  out.SynchronizeTo(f);
418 
419  if (remove1) {
420  in1.RemoveMagBuffer();
421  in1.RemovePhaseBuffer();
422  in1.UpdateData();
423  }
424  if (remove2) {
425  in2.RemoveMagBuffer();
426  in2.RemovePhaseBuffer();
427  in2.UpdateData();
428  }
429  if (remove3) {
430  out.RemoveMagBuffer();
431  out.RemovePhaseBuffer();
432  out.UpdateData();
433  }
434 //#endif
435  }
436 
437  void SpectrumAdder2::AddComplex(Spectrum& in1, Spectrum& in2, Spectrum& out)
438  {
439  switch(mScaleState) {
440  case Slinlin:
441  AddComplexLin(in1,in2,out);
442  break;
443  case Sloglog:
444  AddComplexLog(in1,in2,out);
445  break;
446  case Slinlog:
447  AddComplexLinLog(in1,in2,out);
448  break;
449  case Sloglin:
450  AddComplexLinLog(in2,in1,out);
451  break;
452  }
453  }
454 
455  void SpectrumAdder2::AddComplexLin(Spectrum& in1, Spectrum& in2, Spectrum& out)
456  {
457  bool remove1=false,remove2=false,remove3=false;
458  SpecTypeFlags f;
459 
460  // This function was choosed because outme of the data objects had
461  // their Complex attribute instantiated. We don't know which of
462  // them, though, out we must check and instantiate the attribute
463  // it it is missed. This could be optimised out by adding more
464  // States, see coments on this in the class declaration.
465  in1.GetType(f);
466  if (!f.bComplex) {
467  remove1=true;
468  f.bComplex=true;
469  in1.SetTypeSynchronize(f);
470  }
471  in2.GetType(f);
472  if (!f.bComplex) {
473  remove2=true;
474  f.bComplex=true;
475  in2.SetTypeSynchronize(f);
476  }
477  out.GetType(f);
478  if (!f.bComplex) {
479  remove3=true;
480  f.bComplex=true;
481  out.SetType(f);
482  }
483 
484  Complex *c1 = in1.GetComplexArray().GetPtr();
485  Complex *c2 = in2.GetComplexArray().GetPtr();
486  Complex *co = out.GetComplexArray().GetPtr();
487  for (int i=0;i<mSize;i++)
488  co[i]=c1[i]+c2[i];
489 
490  f.bMagPhase=f.bPolar=f.bMagPhaseBPF=false;
491  f.bComplex=true;
492  out.SynchronizeTo(f);
493 
494  if (remove1) {
495  in1.RemoveComplexArray();
496  in1.UpdateData();
497  }
498  if (remove2) {
499  in2.RemoveComplexArray();
500  in2.UpdateData();
501  }
502  if (remove3) {
503  out.RemoveComplexArray();
504  out.UpdateData();
505  }
506  }
507 
508 
509  void SpectrumAdder2::AddPolar(Spectrum& in1, Spectrum& in2, Spectrum& out)
510  {
511  switch(mScaleState) {
512  case Slinlin:
513  AddPolarLin(in1,in2,out);
514  break;
515  case Sloglog:
516  AddPolarLog(in1,in2,out);
517  break;
518  case Slinlog:
519  AddPolarLinLog(in1,in2,out);
520  break;
521  case Sloglin:
522  AddPolarLinLog(in2,in1,out);
523  break;
524  }
525  }
526 
527  void SpectrumAdder2::AddPolarLin(Spectrum& in1, Spectrum& in2, Spectrum& out)
528  {
529  bool remove1=false,remove2=false,remove3=false;
530  SpecTypeFlags f;
531 
532  // This function was choosed because outme of the data objects had
533  // their Polar attribute instantiated. We don't know which of
534  // them, though, out we must check and instantiate the attribute
535  // it it is missed. This could be optimised out by adding more
536  // States, see coments on this in the class declaration.
537  in1.GetType(f);
538  if (!f.bPolar) {
539  remove1=true;
540  f.bPolar=true;
541  in1.SetTypeSynchronize(f);
542  }
543  in2.GetType(f);
544  if (!f.bPolar) {
545  remove2=true;
546  f.bPolar=true;
547  in2.SetTypeSynchronize(f);
548  }
549  out.GetType(f);
550  if (!f.bPolar) {
551  remove3=true;
552  f.bPolar=true;
553  out.SetType(f);
554  }
555 
556  Polar *p1 = in1.GetPolarArray().GetPtr();
557  Polar *p2 = in2.GetPolarArray().GetPtr();
558  Polar *po = out.GetPolarArray().GetPtr();
559  for (int i=0;i<mSize;i++)
560  po[i]=p1[i]+p2[i];
561 
562  f.bComplex=f.bMagPhase=f.bMagPhaseBPF=false;
563  f.bPolar=true;
564  out.SynchronizeTo(f);
565 
566  if (remove1) {
567  in1.RemovePolarArray();
568  in1.UpdateData();
569  }
570  if (remove2) {
571  in2.RemovePolarArray();
572  in2.UpdateData();
573  }
574  if (remove3) {
575  out.RemovePolarArray();
576  out.UpdateData();
577  }
578  }
579 
580 
581  void SpectrumAdder2::AddBPFMagPhase(Spectrum& in1, Spectrum& in2, Spectrum& out)
582  {
583  switch(mScaleState) {
584  case Slinlin:
585  AddBPFMagPhaseLin(in1,in2,out);
586  break;
587  case Sloglog:
588  AddBPFMagPhaseLog(in1,in2,out);
589  break;
590  case Slinlog:
591  CLAM_ASSERT(false,"SpectrumAdder2::AddBPFMagPhase(LinLog): Not implemented");
592  break;
593  case Sloglin:
594  AddBPFMagPhaseLogLin(in1,in2,out);
595  break;
596  }
597  }
598 
599  void SpectrumAdder2::AddMagPhaseBPF(Spectrum& in1, Spectrum& in2, Spectrum& out)
600  {
601  switch(mScaleState) {
602  case Slinlin:
603  AddBPFMagPhaseLin(in2,in1,out);
604  break;
605  case Sloglog:
606  AddBPFMagPhaseLog(in2,in1,out);
607  break;
608  case Slinlog:
609  AddBPFMagPhaseLogLin(in2,in1,out);
610  break;
611  case Sloglin:
612  CLAM_ASSERT(false,"SpectrumAdder2::AddMagPhaseBPF(LinLog): Not implemented");
613  break;
614  }
615  }
616 
617  void SpectrumAdder2::AddBPFMagPhaseLin(Spectrum& in1, Spectrum& in2, Spectrum& out)
618  {
619  bool remove2=false,remove3=false;
620  SpecTypeFlags f;
621 
622  // This function was choosed because in1 is a BPF Spectrum,
623  // and outme of the non-BPF data objects have their MagPhase
624  // attribute instantiated. We don't know which of them,
625  // though, out we must check and instantiate the attribute it
626  // it is missed. This could be optimised out by adding more
627  // States, see coments on this in the class declaration.
628  in2.GetType(f);
629  if (!f.bMagPhase) {
630  remove2=true;
631  f.bMagPhase=true;
632  in2.SetTypeSynchronize(f);
633  }
634  out.GetType(f);
635  if (!f.bMagPhase) {
636  remove3=true;
637  f.bMagPhase=true;
638  out.SetType(f);
639  }
640 
641  TData pos = 0.0;
642  TData delta = out.GetSpectralRange() /
643  ((TData)out.GetSize()-TData(1.0));
644  BPF &m1 = in1.GetMagBPF();
645  BPF &f1 = in1.GetPhaseBPF();
646  TData *m2 = in2.GetMagBuffer().GetPtr();
647  TData *f2 = in2.GetPhaseBuffer().GetPtr();
648  TData *mo = out.GetMagBuffer().GetPtr();
649  TData *fo = out.GetPhaseBuffer().GetPtr();
650  for (int i=0;i<mSize;i++) {
651  Polar po = Polar(m1.GetValue(pos),f1.GetValue(pos)) +
652  Polar(m2[i],f2[i]);
653  mo[i]=po.Mag();
654  fo[i]=po.Ang();
655  pos+=delta;
656  }
657 
658  f.bComplex=f.bPolar=f.bMagPhaseBPF=false;
659  f.bMagPhase=true;
660  out.SynchronizeTo(f);
661 
662  if (remove2) {
663  in2.RemoveMagBuffer();
664  in2.RemovePhaseBuffer();
665  in2.UpdateData();
666  }
667  if (remove3) {
668  out.RemoveMagBuffer();
669  out.RemovePhaseBuffer();
670  out.UpdateData();
671  }
672  }
673 
674  void SpectrumAdder2::AddBPFMagPhaseLogLin(Spectrum& in1, Spectrum& in2, Spectrum& out)
675  {
676  bool remove2=false,remove3=false;
677  SpecTypeFlags f;
678 
679  // This function was choosed because in1 is a BPF Spectrum,
680  // and outme of the non-BPF data objects have their MagPhase
681  // attribute instantiated. We don't know which of them,
682  // though, out we must check and instantiate the attribute it
683  // it is missed. This could be optimised out by adding more
684  // States, see coments on this in the class declaration.
685  in2.GetType(f);
686  if (!f.bMagPhase) {
687  remove2=true;
688  f.bMagPhase=true;
689  in2.SetTypeSynchronize(f);
690  }
691  out.GetType(f);
692  if (!f.bMagPhase) {
693  remove3=true;
694  f.bMagPhase=true;
695  out.SetType(f);
696  }
697 
698  TData pos = 0.0;
699  TData delta = out.GetSpectralRange() /
700  ((TData)out.GetSize()-TData(1.0));
701  BPF &m1 = in1.GetMagBPF();
702  BPF &f1 = in1.GetPhaseBPF();
703  TData *m2 = in2.GetMagBuffer().GetPtr();
704  TData *f2 = in2.GetPhaseBuffer().GetPtr();
705  TData *mo = out.GetMagBuffer().GetPtr();
706  TData *fo = out.GetPhaseBuffer().GetPtr();
707  for (int i=0;i<mSize;i++) {
708  Polar po = Polar(CLAM_pow(TData(10),m1.GetValue(pos)/TData(10.0)),f1.GetValue(pos)) +
709  Polar(m2[i],f2[i]);
710  mo[i]=po.Mag();
711  fo[i]=po.Ang();
712  pos+=delta;
713  }
714 
715  f.bComplex=f.bPolar=f.bMagPhaseBPF=false;
716  f.bMagPhase=true;
717  out.SynchronizeTo(f);
718 
719  if (remove2) {
720  in2.RemoveMagBuffer();
721  in2.RemovePhaseBuffer();
722  in2.UpdateData();
723  }
724  if (remove3) {
725  out.RemoveMagBuffer();
726  out.RemovePhaseBuffer();
727  out.UpdateData();
728  }
729  }
730 
731  void SpectrumAdder2::AddBPFComplex(Spectrum& in1, Spectrum& in2, Spectrum& out)
732  {
733  switch(mScaleState) {
734  case Slinlin:
735  AddBPFComplexLin(in1,in2,out);
736  break;
737  case Sloglog:
738  AddBPFComplexLog(in1,in2,out);
739  break;
740  case Slinlog:
741  CLAM_ASSERT(false,"SpectrumAdder2::AddBPFMagPhase(LinLog): Not implemented");
742  break;
743  case Sloglin:
744  AddBPFComplexLogLin(in1,in2,out);
745  break;
746  }
747  }
748 
749  void SpectrumAdder2::AddComplexBPF(Spectrum& in1, Spectrum& in2, Spectrum& out)
750  {
751  switch(mScaleState) {
752  case Slinlin:
753  AddBPFComplexLin(in2,in1,out);
754  break;
755  case Sloglog:
756  AddBPFComplexLog(in2,in1,out);
757  break;
758  case Slinlog:
759  AddBPFComplexLogLin(in2,in1,out);
760  break;
761  case Sloglin:
762  CLAM_ASSERT(false,"SpectrumAdder2::AddBPFMagPhase(LinLog): Not implemented");
763  break;
764  }
765  }
766 
767  void SpectrumAdder2::AddBPFComplexLin(Spectrum& in1, Spectrum& in2, Spectrum& out)
768  {
769  bool remove2=false,remove3=false;
770  SpecTypeFlags f;
771 
772  // This function was choosed because in1 is a BPF Spectrum,
773  // and outme of the non-BPF data objects have their Complex
774  // attribute instantiated. We don't know which of them,
775  // though, out we must check and instantiate the attribute it
776  // it is missed. This could be optimised out by adding more
777  // States, see coments on this in the class declaration.
778  in2.GetType(f);
779  if (!f.bComplex) {
780  remove2=true;
781  f.bComplex=true;
782  in2.SetTypeSynchronize(f);
783  }
784  out.GetType(f);
785  if (!f.bComplex) {
786  remove3=true;
787  f.bComplex=true;
788  out.SetType(f);
789  }
790 
791  TData pos = 0.0;
792  TData delta = out.GetSpectralRange() /
793  ((TData)out.GetSize()-TData(1.0));
794  BPF &m1 = in1.GetMagBPF();
795  BPF &f1 = in1.GetPhaseBPF();
796  Complex *c2 = in2.GetComplexArray().GetPtr();
797  Complex *co = out.GetComplexArray().GetPtr();
798  for (int i=0;i<mSize;i++) {
799  TData BRe = fabs(m1.GetValue(pos)) * CLAM_cos(f1.GetValue(pos));
800  TData BIm = fabs(m1.GetValue(pos)) * CLAM_sin(f1.GetValue(pos));
801  co[i]= Complex(BRe,BIm) + c2[i];
802  pos+=delta;
803  }
804 
805  f.bMagPhase=f.bPolar=f.bMagPhaseBPF=false;
806  f.bComplex=true;
807  out.SynchronizeTo(f);
808 
809  if (remove2) {
810  in2.RemoveComplexArray();
811  in2.UpdateData();
812  }
813  if (remove3) {
814  out.RemoveComplexArray();
815  out.UpdateData();
816  }
817  }
818 
819  // This is probably one of the most used methods, because it can be used
820  // to apply a BPF filter in log scale to a linear complex spectrum, as the
821  // one naturaly generated from a FFT
822  void SpectrumAdder2::AddBPFComplexLogLin(Spectrum& in1, Spectrum& in2, Spectrum& out)
823  {
824  bool remove2=false,remove3=false;
825  SpecTypeFlags f;
826 
827  // This function was choosed because in1 is a BPF Spectrum,
828  // and outme of the non-BPF data objects have their Complex
829  // attribute instantiated. We don't know which of them,
830  // though, out we must check and instantiate the attribute it
831  // it is missed. This could be optimised out by adding more
832  // States, see coments on this in the class declaration.
833  in2.GetType(f);
834  if (!f.bComplex) {
835  remove2=true;
836  f.bComplex=true;
837  in2.SetTypeSynchronize(f);
838  }
839  out.GetType(f);
840  if (!f.bComplex) {
841  remove3=true;
842  f.bComplex=true;
843  out.SetType(f);
844  }
845 
846  TData pos = 0.0;
847  TData delta = out.GetSpectralRange() /
848  ((TData)out.GetSize()-TData(1.0));
849  BPF &m1 = in1.GetMagBPF();
850  BPF &f1 = in1.GetPhaseBPF();
851  Complex *c2 = in2.GetComplexArray().GetPtr();
852  Complex *co = out.GetComplexArray().GetPtr();
853  for (int i=0;i<mSize;i++) {
854  TData BRe = CLAM_pow(TData(10),fabs(m1.GetValue(pos))/TData(10.0)) * CLAM_cos(f1.GetValue(pos));
855  TData BIm = CLAM_pow(TData(10),fabs(m1.GetValue(pos))/TData(10.0)) * CLAM_sin(f1.GetValue(pos));
856  co[i]= Complex(BRe,BIm) + c2[i];
857  pos+=delta;
858  }
859 
860  f.bMagPhase=f.bPolar=f.bMagPhaseBPF=false;
861  f.bComplex=true;
862  out.SynchronizeTo(f);
863 
864 
865  if (remove2) {
866  in2.RemoveComplexArray();
867  in2.UpdateData();
868  }
869  if (remove3) {
870  out.RemoveComplexArray();
871  out.UpdateData();
872  }
873  }
874 
875 
876  void SpectrumAdder2::AddBPFPolar(Spectrum& in1, Spectrum& in2, Spectrum& out)
877  {
878  switch(mScaleState) {
879  case Slinlin:
880  AddBPFPolarLin(in1,in2,out);
881  break;
882  case Sloglog:
883  AddBPFPolarLog(in1,in2,out);
884  break;
885  case Slinlog:
886  CLAM_ASSERT(false,"SpectrumAdder2::AddBPFPolar(LinLog): Not implemented");
887  break;
888  case Sloglin:
889  AddBPFPolarLogLin(in1,in2,out);
890  break;
891  }
892  }
893 
894  void SpectrumAdder2::AddPolarBPF(Spectrum& in1, Spectrum& in2, Spectrum& out)
895  {
896  switch(mScaleState) {
897  case Slinlin:
898  AddBPFPolarLin(in2,in1,out);
899  break;
900  case Sloglog:
901  AddBPFPolarLog(in2,in1,out);
902  break;
903  case Slinlog:
904  AddBPFPolarLogLin(in2,in1,out);
905  break;
906  case Sloglin:
907  CLAM_ASSERT(false,"SpectrumAdder2::AddBPFPolar(LinLog): Not implemented");
908  break;
909  }
910  }
911 
912  void SpectrumAdder2::AddBPFPolarLin(Spectrum& in1, Spectrum& in2, Spectrum& out)
913  {
914  bool remove2=false,remove3=false;
915  SpecTypeFlags f;
916 
917  // This function was choosed because in1 is a BPF Spectrum,
918  // and outme of the non-BPF data objects have their Polar
919  // attribute instantiated. We don't know which of them,
920  // though, out we must check and instantiate the attribute it
921  // it is missed. This could be optimised out by adding more
922  // States, see coments on this in the class declaration.
923  in2.GetType(f);
924  if (!f.bPolar) {
925  remove2=true;
926  f.bPolar=true;
927  in2.SetTypeSynchronize(f);
928  }
929  out.GetType(f);
930  if (!f.bPolar) {
931  remove3=true;
932  f.bPolar=true;
933  out.SetType(f);
934  }
935 
936  TData pos = 0.0;
937  TData delta = out.GetSpectralRange() /
938  ((TData)out.GetSize()-TData(1.0));
939  BPF &m1 = in1.GetMagBPF();
940  BPF &f1 = in1.GetPhaseBPF();
941  Polar *p2 = in2.GetPolarArray().GetPtr();
942  Polar *po = out.GetPolarArray().GetPtr();
943  for (int i=0;i<mSize;i++) {
944  po[i]=Polar(m1.GetValue(pos),f1.GetValue(pos))+p2[i];
945  pos+=delta;
946  }
947 
948  f.bMagPhase=f.bComplex=f.bMagPhaseBPF=false;
949  f.bPolar=true;
950  out.SynchronizeTo(f);
951 
952  if (remove2) {
953  in2.RemovePolarArray();
954  in2.UpdateData();
955  }
956  if (remove3) {
957  out.RemovePolarArray();
958  out.UpdateData();
959  }
960  }
961 
962  void SpectrumAdder2::AddBPFPolarLogLin(Spectrum& in1, Spectrum& in2, Spectrum& out)
963  {
964  bool remove2=false,remove3=false;
965  SpecTypeFlags f;
966 
967  // This function was choosed because in1 is a BPF Spectrum,
968  // and outme of the non-BPF data objects have their Polar
969  // attribute instantiated. We don't know which of them,
970  // though, out we must check and instantiate the attribute it
971  // it is missed. This could be optimised out by adding more
972  // States, see coments on this in the class declaration.
973  in2.GetType(f);
974  if (!f.bPolar) {
975  remove2=true;
976  f.bPolar=true;
977  in2.SetTypeSynchronize(f);
978  }
979  out.GetType(f);
980  if (!f.bPolar) {
981  remove3=true;
982  f.bPolar=true;
983  out.SetType(f);
984  }
985 
986  TData pos = 0.0;
987  TData delta = out.GetSpectralRange() /
988  ((TData)out.GetSize()-TData(1.0));
989  BPF &m1 = in1.GetMagBPF();
990  BPF &f1 = in1.GetPhaseBPF();
991  Polar *p2 = in2.GetPolarArray().GetPtr();
992  Polar *po = out.GetPolarArray().GetPtr();
993  for (int i=0;i<mSize;i++) {
994  TData BMag = CLAM_pow(TData(10),m1.GetValue(pos)/TData(10.0));
995  TData BPha = f1.GetValue(pos);
996  po[i]=Polar(BMag,BPha)+p2[i];
997  pos+=delta;
998  }
999 
1000  f.bMagPhase=f.bComplex=f.bMagPhaseBPF=false;
1001  f.bPolar=true;
1002  out.SynchronizeTo(f);
1003 
1004  if (remove2) {
1005  in2.RemovePolarArray();
1006  in2.UpdateData();
1007  }
1008  if (remove3) {
1009  out.RemovePolarArray();
1010  out.UpdateData();
1011  }
1012  }
1013 
1014  void SpectrumAdder2::AddBPF(Spectrum& in1, Spectrum& in2, Spectrum& out)
1015  {
1016  // First we check if the abcisas agree
1017 
1018  for (int i=0;i<mSize;i++) {
1019  Point &pm1=in1.GetMagBPF().GetPointArray()[i];
1020  Point &pm2=in2.GetMagBPF().GetPointArray()[i];
1021  Point &pmo=out.GetMagBPF().GetPointArray()[i];
1022  Point &pf1=in1.GetPhaseBPF().GetPointArray()[i];
1023  Point &pf2=in2.GetPhaseBPF().GetPointArray()[i];
1024  Point &pfo=out.GetPhaseBPF().GetPointArray()[i];
1025  CLAM_ASSERT(pm1.GetX() == pm2.GetX(), "InterpolateBPF: input BPF abcisas do not match "
1026  "(and BPF merging not yet iplemented)");
1027  CLAM_ASSERT(pm1.GetX() == pmo.GetX(), "InterpolateBPF: ouput BPF abcisas do not match with imput "
1028  "(and BPF merging not yet iplemented)");
1029  pmo.SetY(pm1.GetY()*pm2.GetY());
1030  pfo.SetY(pf1.GetY()+pf2.GetY());
1031  }
1032 
1033  }
1034 
1035  // UNINMPLEMENTED METHODS. some day...
1036  void SpectrumAdder2::AddMagPhaseLog(Spectrum& in1, Spectrum& in2, Spectrum& out)
1037  {
1038  CLAM_ASSERT(false,"AddMagPhaseLog: Not implemented");
1039  }
1040  void SpectrumAdder2::AddMagPhaseLinLog(Spectrum& in1, Spectrum& in2, Spectrum& out)
1041  {
1042  CLAM_ASSERT(false,"AddMagPhaseLinLog: Not implemented");
1043  }
1044  void SpectrumAdder2::AddComplexLog(Spectrum& in1, Spectrum& in2, Spectrum& out)
1045  {
1046  CLAM_ASSERT(false,"AddComplexLog: Not implemented");
1047  }
1048  void SpectrumAdder2::AddComplexLinLog(Spectrum& in1, Spectrum& in2, Spectrum& out)
1049  {
1050  CLAM_ASSERT(false,"AddComplexLinLog: Not implemented");
1051  }
1052  void SpectrumAdder2::AddPolarLog(Spectrum& in1, Spectrum& in2, Spectrum& out)
1053  {
1054  CLAM_ASSERT(false,"AddPolarLog: Not implemented");
1055  }
1056  void SpectrumAdder2::AddPolarLinLog(Spectrum& in1, Spectrum& in2, Spectrum& out)
1057  {
1058  CLAM_ASSERT(false,"AddPolarLinLog: Not implemented");
1059  }
1060  void SpectrumAdder2::AddBPFComplexLog(Spectrum& in1, Spectrum& in2, Spectrum& out)
1061  {
1062  CLAM_ASSERT(false,"AddBPFComplexLog: Not implemented");
1063  }
1064  void SpectrumAdder2::AddBPFComplexLinLog(Spectrum& in1, Spectrum& in2, Spectrum& out)
1065  {
1066  CLAM_ASSERT(false,"AddBPFComplexLinLog: Not implemented");
1067  }
1068  void SpectrumAdder2::AddBPFPolarLog(Spectrum& in1, Spectrum& in2, Spectrum& out)
1069  {
1070  CLAM_ASSERT(false,"AddBPFPolarLog: Not implemented");
1071  }
1072  void SpectrumAdder2::AddBPFPolarLinLog(Spectrum& in1, Spectrum& in2, Spectrum& out)
1073  {
1074  CLAM_ASSERT(false,"AddBPFPolarLinLog: Not implemented");
1075  }
1076  void SpectrumAdder2::AddBPFMagPhaseLog(Spectrum& in1, Spectrum& in2, Spectrum& out)
1077  {
1078  CLAM_ASSERT(false,"AddBPFMagPhaseLog: Not implemented");
1079  }
1080  void SpectrumAdder2::AddBPFMagPhaseLinLog(Spectrum& in1, Spectrum& in2, Spectrum& out)
1081  {
1082  CLAM_ASSERT(false,"AddBPFMagPhaseLinLog: Not implemented");
1083  }
1084 
1085 }
1086