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