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