CLAM-Development
1.1
|
00001 /* 00002 * Copyright (c) 2001-2004 MUSIC TECHNOLOGY GROUP (MTG) 00003 * UNIVERSITAT POMPEU FABRA 00004 * 00005 * 00006 * This program is free software; you can redistribute it and/or modify 00007 * it under the terms of the GNU General Public License as published by 00008 * the Free Software Foundation; either version 2 of the License, or 00009 * (at your option) any later version. 00010 * 00011 * This program is distributed in the hope that it will be useful, 00012 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00014 * GNU General Public License for more details. 00015 * 00016 * You should have received a copy of the GNU General Public License 00017 * along with this program; if not, write to the Free Software 00018 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 00019 * 00020 */ 00021 00022 #include "Complex.hxx" 00023 #include "SpectrumProduct.hxx" 00024 #include "SpectrumConfig.hxx" 00025 #include "ProcessingFactory.hxx" 00026 00027 namespace CLAM 00028 { 00029 00030 namespace Hidden 00031 { 00032 static const char * metadata[] = { 00033 "key", "SpectrumProduct", 00034 "category", "Arithmetic Operations", 00035 "description", "SpectrumProduct", 00036 0 00037 }; 00038 static FactoryRegistrator<ProcessingFactory, SpectrumProduct> reg = metadata; 00039 } 00040 00041 SpectrumProduct::SpectrumProduct(const Config &c) 00042 : mSize(0), 00043 mProtoState(SOther), 00044 mInput1("Input 1",this), 00045 mInput2("Input 2",this), 00046 mOutput("Output",this) 00047 { 00048 Configure(c); 00049 } 00050 00051 SpectrumProduct::~SpectrumProduct() 00052 { 00053 } 00054 00055 bool SpectrumProduct::Do(Spectrum& in1, Spectrum& in2, Spectrum& out) 00056 { 00057 CLAM_DEBUG_ASSERT(IsRunning(), 00058 "SpectrumProduct::Do(): Not in execution mode"); 00059 00060 switch (mProtoState) { 00061 // Fast prototype configurations 00062 case SMagPhase: 00063 MultiplyMagPhase(in1,in2,out); 00064 break; 00065 case SComplex: 00066 MultiplyComplex(in1,in2,out); 00067 break; 00068 case SPolar: 00069 MultiplyPolar(in1,in2,out); 00070 break; 00071 case SBPF: 00072 MultiplyBPF(in1,in2,out); 00073 break; 00074 case SBPFMagPhase: 00075 MultiplyBPFMagPhase(in1,in2,out); 00076 break; 00077 case SBPFComplex: 00078 MultiplyBPFComplex(in1,in2,out); 00079 break; 00080 case SBPFPolar: 00081 MultiplyBPFPolar(in1,in2,out); 00082 break; 00083 case SMagPhaseBPF: 00084 MultiplyMagPhaseBPF(in1,in2,out); 00085 break; 00086 case SComplexBPF: 00087 MultiplyComplexBPF(in1,in2,out); 00088 break; 00089 case SPolarBPF: 00090 MultiplyPolarBPF(in1,in2,out); 00091 break; 00092 // Slow prototype configurations 00093 case SOther: 00094 Multiply(in1,in2,out); 00095 break; 00096 default: 00097 CLAM_ASSERT(false,"Do(...) : internal inconsistency (invalid mProtoState)"); 00098 } 00099 00100 return true; 00101 } 00102 00103 bool SpectrumProduct::Do() 00104 { 00105 const Spectrum& in1 = mInput1.GetData(); 00106 const Spectrum& in2 = mInput2.GetData(); 00107 Spectrum& out = mOutput.GetData(); 00108 00109 if (in1.HasComplexArray()) 00110 std::cout << "in1.HasComplexArray()" << std::endl; 00111 00112 CLAM_DEBUG_ASSERT( in1.GetSize()==in2.GetSize(), "Expected two spectrums of the same size"); 00113 out.SetSize( in1.GetSize() ); 00114 00115 bool res = Do(mInput1.GetData(),mInput2.GetData(),mOutput.GetData()); 00116 mInput1.Consume(); 00117 mInput2.Consume(); 00118 mOutput.Produce(); 00119 return res; 00120 } 00121 00122 // This function analyses the inputs and decides which prototypes to use 00123 // For the product computation. 00124 bool SpectrumProduct::SetPrototypes(const Spectrum& in1,const Spectrum& in2,const Spectrum& out) 00125 { 00126 // Check common attributes 00127 SpectrumConfig s1; 00128 in1.GetConfig(s1); 00129 SpectrumConfig s2; 00130 in2.GetConfig(s2); 00131 SpectrumConfig so; 00132 out.GetConfig(so); 00133 SpecTypeFlags t1; 00134 in1.GetType(t1); 00135 SpecTypeFlags t2; 00136 in2.GetType(t2); 00137 SpecTypeFlags to; 00138 out.GetType(to); 00139 00140 // Sanity check: 00141 CLAM_ASSERT(t1.bMagPhase || t1.bComplex || t1.bPolar || t1.bMagPhaseBPF, 00142 "SpectrumProducts: First input Spectrum without content"); 00143 CLAM_ASSERT(t2.bMagPhase || t2.bComplex || t2.bPolar || t2.bMagPhaseBPF, 00144 "SpectrumProducts: Second input Spectrum without content"); 00145 CLAM_ASSERT(to.bMagPhase || to.bComplex || to.bPolar || to.bMagPhaseBPF, 00146 "SpectrumProducts: Output Spectrum object without content"); 00147 00148 // Product size. "pure" BPFs are not considered here. 00149 mSize = 0; 00150 if (t1.bMagPhase || t1.bComplex || t1.bPolar) { 00151 mSize = in1.GetSize(); 00152 CLAM_ASSERT(mSize,"SpectrumProduct::SetPrototypes: Zero size spectrum"); 00153 } 00154 if (t2.bMagPhase || t2.bComplex || t2.bPolar) 00155 { 00156 CLAM_ASSERT(in2.GetSize(),"SpectrumProduct::SetPrototypes: Zero size spectrum"); 00157 if (!mSize) mSize = in2.GetSize(); 00158 else CLAM_ASSERT(mSize == in2.GetSize(), 00159 "SpectrumProduct::SetPrototypes: Sizes Mismatch"); 00160 } 00161 if (to.bMagPhase || to.bComplex || to.bPolar) 00162 { 00163 CLAM_ASSERT(out.GetSize(),"SpectrumProduct::SetPrototypes: Zero size spectrum"); 00164 if (!mSize) mSize = out.GetSize(); 00165 else CLAM_ASSERT(mSize == out.GetSize(), 00166 "SpectrumProduct::SetPrototypes: Output size Mismatch"); 00167 } 00168 00169 // Spectral Range. 00170 // We could also ignore BPF-only objects here, but in 00171 // practice, if a BPF is designed for a certain spectral 00172 // range, error will probably be too big out of the range, so 00173 // we always force range matching 00174 CLAM_ASSERT(in1.GetSpectralRange() == in2.GetSpectralRange(), 00175 "SpectrumProduct::SetPrototypes: Spectral range mismatch on inputs"); 00176 CLAM_ASSERT(in1.GetSpectralRange() == out.GetSpectralRange(), 00177 "SpectrumProduct::SetPrototypes: Spectral range mismatch on output"); 00178 00179 // Scale. 00180 if (in1.GetScale() == EScale::eLinear) 00181 if (in2.GetScale() == EScale::eLinear) 00182 mScaleState=Slinlin; 00183 else 00184 mScaleState=Slinlog; 00185 else 00186 if (in2.GetScale() == EScale::eLinear) 00187 mScaleState=Sloglin; 00188 else 00189 mScaleState=Sloglog; 00190 // Log scale output might be useful, for example when working 00191 // with BPF objects at the three ports. But right for now... 00192 CLAM_ASSERT(out.GetScale() != EScale::eLog, 00193 "SpectrumProduct: Log Scale Output not implemented"); 00194 00195 // Prototypes. 00196 00197 // BPF PRODUCTS. 00198 bool i1BPF=false, i2BPF=false, oBPF=false; 00199 if (t1.bMagPhaseBPF && !t1.bComplex && !t1.bPolar && !t1.bMagPhase) 00200 i1BPF=true; 00201 if (t2.bMagPhaseBPF && !t2.bComplex && !t2.bPolar && !t2.bMagPhase) 00202 i2BPF=true; 00203 if (to.bMagPhaseBPF && !to.bComplex && !to.bPolar && !to.bMagPhase) 00204 oBPF=true; 00205 00206 if (oBPF) { 00207 // BPF output requires interpolating the inputs. 00208 mProtoState=SBPF; 00209 return true; 00210 } 00211 if (i1BPF) { 00212 // States with direct BPF implementation. 00213 if (t2.bMagPhase && to.bMagPhase) { 00214 mProtoState=SBPFMagPhase; 00215 return true; 00216 } 00217 if (t2.bComplex && to.bComplex) { 00218 mProtoState=SBPFComplex; 00219 return true; 00220 } 00221 if (t2.bPolar && to.bPolar) { 00222 mProtoState=SBPFPolar; 00223 return true; 00224 } 00225 // States requiring 1 conversion: 00226 if (t2.bMagPhase || to.bMagPhase) { 00227 mProtoState=SBPFMagPhase; 00228 return true; 00229 } 00230 if (t2.bComplex || to.bComplex) { 00231 mProtoState=SBPFComplex; 00232 return true; 00233 } 00234 if (t2.bPolar || to.bPolar) { 00235 mProtoState=SBPFPolar; 00236 return true; 00237 } 00238 // Should never get here: 00239 CLAM_ASSERT(false, 00240 "SpectrumProduct::SetPrototypes: Data flags internal inconsistency"); 00241 } 00242 if (i2BPF) { 00243 // States with direct BPF implementation. 00244 if (t1.bMagPhase && to.bMagPhase) { 00245 mProtoState=SMagPhaseBPF; 00246 return true; 00247 } 00248 if (t1.bComplex && to.bComplex) { 00249 mProtoState=SComplexBPF; 00250 return true; 00251 } 00252 if (t1.bPolar && to.bPolar) { 00253 mProtoState=SPolarBPF; 00254 return true; 00255 } 00256 // States requiring 1 conversion: 00257 if (t1.bMagPhase || to.bMagPhase) { 00258 mProtoState=SMagPhaseBPF; 00259 return true; 00260 } 00261 if (t1.bComplex || to.bComplex) { 00262 mProtoState=SComplexBPF; 00263 } 00264 if (t1.bPolar || to.bPolar) { 00265 mProtoState=SPolarBPF; 00266 return true; 00267 } 00268 // Should never get here: 00269 CLAM_ASSERT(false, "SpectrumProduct::SetPrototypes:" 00270 " invalid data flags"); 00271 } 00272 // Direct non-BPF states. 00273 if (t1.bMagPhase && t2.bMagPhase && to.bMagPhase) { 00274 mProtoState=SMagPhase; 00275 return true; 00276 } 00277 if (t1.bComplex && t2.bComplex && to.bComplex) { 00278 mProtoState=SComplex; 00279 return true; 00280 } 00281 if (t1.bPolar && t2.bPolar && to.bPolar) { 00282 mProtoState=SPolar; 00283 return true; 00284 } 00285 // States Requiring 1 Conversion 00286 if ( (t1.bMagPhase && t2.bMagPhase) || 00287 (t1.bMagPhase && to.bMagPhase) || 00288 (t2.bMagPhase && to.bMagPhase)) { 00289 mProtoState=SMagPhase; 00290 return true; 00291 } 00292 if ( (t1.bComplex && t2.bComplex) || 00293 (t1.bComplex && to.bComplex) || 00294 (t2.bComplex && to.bComplex)) { 00295 mProtoState=SComplex; 00296 return true; 00297 } 00298 if ( (t1.bPolar && t2.bPolar) || 00299 (t1.bPolar && to.bPolar) || 00300 (t2.bPolar && to.bPolar)) { 00301 mProtoState=SPolar; 00302 return true; 00303 } 00304 // Bad luck. We require 2 conversions... 00305 mProtoState=SMagPhase; 00306 return true; 00307 } 00308 00309 00310 bool SpectrumProduct::SetPrototypes() 00311 { 00312 CLAM_ASSERT(false,"SpectrumProduct::SetPrototypes(): Not implemented"); 00313 return true; 00314 } 00315 00316 bool SpectrumProduct::UnsetPrototypes() 00317 { 00318 mProtoState=SOther; 00319 return true; 00320 } 00321 00322 00323 void SpectrumProduct::Multiply(Spectrum& in1, Spectrum& in2, Spectrum& out) 00324 { 00325 PrototypeState state_copy = mProtoState; 00326 ScaleState state2_copy = mScaleState; 00327 00328 SetPrototypes(in1,in2,out); 00329 Do(in1,in2,out); 00330 00331 mProtoState = state_copy; 00332 mScaleState = state2_copy; 00333 } 00334 00335 00336 void SpectrumProduct::MultiplyMagPhase(Spectrum& in1, Spectrum& in2, Spectrum& out) 00337 { 00338 switch(mScaleState) { 00339 case Slinlin: 00340 MultiplyMagPhaseLin(in1,in2,out); 00341 break; 00342 case Sloglog: 00343 MultiplyMagPhaseLog(in1,in2,out); 00344 break; 00345 case Slinlog: 00346 MultiplyMagPhaseLinLog(in1,in2,out); 00347 break; 00348 case Sloglin: 00349 MultiplyMagPhaseLinLog(in2,in1,out); 00350 break; 00351 } 00352 } 00353 00354 void SpectrumProduct::MultiplyMagPhaseLin(Spectrum& in1, Spectrum& in2, Spectrum& out) 00355 { 00356 bool remove1=false,remove2=false,remove3=false; 00357 SpecTypeFlags f; 00358 00359 // This function was choosed because some of the data objects had 00360 // their MagPhase attribute instantiated. We don't know which of 00361 // them, though, so we must check and instantiate the attribute 00362 // it it is missed. This could be optimised out by adding more 00363 // States, see coments on this in the class declaration. 00364 in1.GetType(f); 00365 if (!f.bMagPhase) { 00366 remove1=true; 00367 f.bMagPhase=true; 00368 in1.SetTypeSynchronize(f); 00369 } 00370 in2.GetType(f); 00371 if (!f.bMagPhase) { 00372 remove2=true; 00373 f.bMagPhase=true; 00374 in2.SetTypeSynchronize(f); 00375 } 00376 out.GetType(f); 00377 if (!f.bMagPhase) { 00378 remove3=true; 00379 f.bMagPhase=true; 00380 out.SetType(f); 00381 } 00382 00383 TData *m1 = in1.GetMagBuffer().GetPtr(); 00384 TData *f1 = in1.GetPhaseBuffer().GetPtr(); 00385 TData *m2 = in2.GetMagBuffer().GetPtr(); 00386 TData *f2 = in2.GetPhaseBuffer().GetPtr(); 00387 TData *mo = out.GetMagBuffer().GetPtr(); 00388 TData *fo = out.GetPhaseBuffer().GetPtr(); 00389 for (int i=0;i<mSize;i++) { 00390 mo[i]=m1[i]*m2[i]; 00391 fo[i]=f1[i]+f2[i]; 00392 } 00393 00394 f.bComplex=f.bPolar=f.bMagPhaseBPF=false; 00395 f.bMagPhase=true; 00396 out.SynchronizeTo(f); 00397 00398 if (remove1) { 00399 in1.RemoveMagBuffer(); 00400 in1.RemovePhaseBuffer(); 00401 in1.UpdateData(); 00402 } 00403 if (remove2) { 00404 in2.RemoveMagBuffer(); 00405 in2.RemovePhaseBuffer(); 00406 in2.UpdateData(); 00407 } 00408 if (remove3) { 00409 out.RemoveMagBuffer(); 00410 out.RemovePhaseBuffer(); 00411 out.UpdateData(); 00412 } 00413 00414 } 00415 00416 void SpectrumProduct::MultiplyComplex(Spectrum& in1, Spectrum& in2, Spectrum& out) 00417 { 00418 switch(mScaleState) { 00419 case Slinlin: 00420 MultiplyComplexLin(in1,in2,out); 00421 break; 00422 case Sloglog: 00423 MultiplyComplexLog(in1,in2,out); 00424 break; 00425 case Slinlog: 00426 MultiplyComplexLinLog(in1,in2,out); 00427 break; 00428 case Sloglin: 00429 MultiplyComplexLinLog(in2,in1,out); 00430 break; 00431 } 00432 } 00433 00434 void SpectrumProduct::MultiplyComplexLin(Spectrum& in1, Spectrum& in2, Spectrum& out) 00435 { 00436 bool remove1=false,remove2=false,remove3=false; 00437 SpecTypeFlags f; 00438 00439 // This function was choosed because some of the data objects had 00440 // their Complex attribute instantiated. We don't know which of 00441 // them, though, so we must check and instantiate the attribute 00442 // it it is missed. This could be optimised out by adding more 00443 // States, see coments on this in the class declaration. 00444 in1.GetType(f); 00445 if (!f.bComplex) { 00446 remove1=true; 00447 f.bComplex=true; 00448 in1.SetTypeSynchronize(f); 00449 } 00450 in2.GetType(f); 00451 if (!f.bComplex) { 00452 remove2=true; 00453 f.bComplex=true; 00454 in2.SetTypeSynchronize(f); 00455 } 00456 out.GetType(f); 00457 if (!f.bComplex) { 00458 remove3=true; 00459 f.bComplex=true; 00460 out.SetType(f); 00461 } 00462 00463 Complex *c1 = in1.GetComplexArray().GetPtr(); 00464 Complex *c2 = in2.GetComplexArray().GetPtr(); 00465 Complex *co = out.GetComplexArray().GetPtr(); 00466 for (int i=0;i<mSize;i++) 00467 co[i]=c1[i]*c2[i]; 00468 00469 f.bMagPhase=f.bPolar=f.bMagPhaseBPF=false; 00470 f.bComplex=true; 00471 out.SynchronizeTo(f); 00472 00473 if (remove1) { 00474 in1.RemoveComplexArray(); 00475 in1.UpdateData(); 00476 } 00477 if (remove2) { 00478 in2.RemoveComplexArray(); 00479 in2.UpdateData(); 00480 } 00481 if (remove3) { 00482 out.RemoveComplexArray(); 00483 out.UpdateData(); 00484 } 00485 } 00486 00487 00488 void SpectrumProduct::MultiplyPolar(Spectrum& in1, Spectrum& in2, Spectrum& out) 00489 { 00490 switch(mScaleState) { 00491 case Slinlin: 00492 MultiplyPolarLin(in1,in2,out); 00493 break; 00494 case Sloglog: 00495 MultiplyPolarLog(in1,in2,out); 00496 break; 00497 case Slinlog: 00498 MultiplyPolarLinLog(in1,in2,out); 00499 break; 00500 case Sloglin: 00501 MultiplyPolarLinLog(in2,in1,out); 00502 break; 00503 } 00504 } 00505 00506 void SpectrumProduct::MultiplyPolarLin(Spectrum& in1, Spectrum& in2, Spectrum& out) 00507 { 00508 bool remove1=false,remove2=false,remove3=false; 00509 SpecTypeFlags f; 00510 00511 // This function was choosed because some of the data objects had 00512 // their Polar attribute instantiated. We don't know which of 00513 // them, though, so we must check and instantiate the attribute 00514 // it it is missed. This could be optimised out by adding more 00515 // States, see coments on this in the class declaration. 00516 in1.GetType(f); 00517 if (!f.bPolar) { 00518 remove1=true; 00519 f.bPolar=true; 00520 in1.SetTypeSynchronize(f); 00521 } 00522 in2.GetType(f); 00523 if (!f.bPolar) { 00524 remove2=true; 00525 f.bPolar=true; 00526 in2.SetTypeSynchronize(f); 00527 } 00528 out.GetType(f); 00529 if (!f.bPolar) { 00530 remove3=true; 00531 f.bPolar=true; 00532 out.SetType(f); 00533 } 00534 00535 Polar *p1 = in1.GetPolarArray().GetPtr(); 00536 Polar *p2 = in2.GetPolarArray().GetPtr(); 00537 Polar *po = out.GetPolarArray().GetPtr(); 00538 for (int i=0;i<mSize;i++) 00539 po[i]=p1[i]*p2[i]; 00540 00541 f.bComplex=f.bMagPhase=f.bMagPhaseBPF=false; 00542 f.bPolar=true; 00543 out.SynchronizeTo(f); 00544 00545 if (remove1) { 00546 in1.RemovePolarArray(); 00547 in1.UpdateData(); 00548 } 00549 if (remove2) { 00550 in2.RemovePolarArray(); 00551 in2.UpdateData(); 00552 } 00553 if (remove3) { 00554 out.RemovePolarArray(); 00555 out.UpdateData(); 00556 } 00557 } 00558 00559 00560 void SpectrumProduct::MultiplyBPFMagPhase(Spectrum& in1, Spectrum& in2, Spectrum& out) 00561 { 00562 switch(mScaleState) { 00563 case Slinlin: 00564 MultiplyBPFMagPhaseLin(in1,in2,out); 00565 break; 00566 case Sloglog: 00567 MultiplyBPFMagPhaseLog(in1,in2,out); 00568 break; 00569 case Slinlog: 00570 CLAM_ASSERT(false,"MultiplyBPFMagPhaseLinLog: Not implemented"); 00571 break; 00572 case Sloglin: 00573 MultiplyBPFMagPhaseLogLin(in1,in2,out); 00574 break; 00575 } 00576 } 00577 00578 void SpectrumProduct::MultiplyMagPhaseBPF(Spectrum& in1, Spectrum& in2, Spectrum& out) 00579 { 00580 switch(mScaleState) { 00581 case Slinlin: 00582 MultiplyBPFMagPhaseLin(in2,in1,out); 00583 break; 00584 case Sloglog: 00585 MultiplyBPFMagPhaseLog(in2,in1,out); 00586 break; 00587 case Slinlog: 00588 MultiplyBPFMagPhaseLogLin(in2,in1,out); 00589 break; 00590 case Sloglin: 00591 CLAM_ASSERT(false,"MultiplyBPFMagPhaseLinLog: Not implemented"); 00592 break; 00593 } 00594 } 00595 00596 void SpectrumProduct::MultiplyBPFMagPhaseLin(Spectrum& in1, Spectrum& in2, Spectrum& out) 00597 { 00598 bool remove2=false,remove3=false; 00599 SpecTypeFlags f; 00600 00601 // This function was choosed because in1 is a BPF Spectrum, 00602 // and some of the non-BPF data objects have their MagPhase 00603 // attribute instantiated. We don't know which of them, 00604 // though, so we must check and instantiate the attribute it 00605 // it is missed. This could be optimised out by adding more 00606 // States, see coments on this in the class declaration. 00607 in2.GetType(f); 00608 if (!f.bMagPhase) { 00609 remove2=true; 00610 f.bMagPhase=true; 00611 in2.SetTypeSynchronize(f); 00612 } 00613 out.GetType(f); 00614 if (!f.bMagPhase) { 00615 remove3=true; 00616 f.bMagPhase=true; 00617 out.SetType(f); 00618 } 00619 00620 TData pos = 0.0; 00621 TData delta = out.GetSpectralRange() / 00622 ((TData)out.GetSize()-TData(1.0)); 00623 BPF &m1 = in1.GetMagBPF(); 00624 BPF &f1 = in1.GetPhaseBPF(); 00625 TData *m2 = in2.GetMagBuffer().GetPtr(); 00626 TData *f2 = in2.GetPhaseBuffer().GetPtr(); 00627 TData *mo = out.GetMagBuffer().GetPtr(); 00628 TData *fo = out.GetPhaseBuffer().GetPtr(); 00629 for (int i=0;i<mSize;i++) { 00630 mo[i]=m1.GetValue(pos)*m2[i]; 00631 fo[i]=f1.GetValue(pos)+f2[i]; 00632 pos+=delta; 00633 } 00634 00635 f.bComplex=f.bPolar=f.bMagPhaseBPF=false; 00636 f.bMagPhase=true; 00637 out.SynchronizeTo(f); 00638 00639 if (remove2) { 00640 in2.RemoveMagBuffer(); 00641 in2.RemovePhaseBuffer(); 00642 in2.UpdateData(); 00643 } 00644 if (remove3) { 00645 out.RemoveMagBuffer(); 00646 out.RemovePhaseBuffer(); 00647 out.UpdateData(); 00648 } 00649 } 00650 00651 void SpectrumProduct::MultiplyBPFMagPhaseLogLin(Spectrum& in1, Spectrum& in2, Spectrum& out) 00652 { 00653 bool remove2=false,remove3=false; 00654 SpecTypeFlags f; 00655 00656 // This function was choosed because in1 is a BPF Spectrum, 00657 // and some of the non-BPF data objects have their MagPhase 00658 // attribute instantiated. We don't know which of them, 00659 // though, so we must check and instantiate the attribute it 00660 // it is missed. This could be optimised out by adding more 00661 // States, see coments on this in the class declaration. 00662 in2.GetType(f); 00663 if (!f.bMagPhase) { 00664 remove2=true; 00665 f.bMagPhase=true; 00666 in2.SetTypeSynchronize(f); 00667 } 00668 out.GetType(f); 00669 if (!f.bMagPhase) { 00670 remove3=true; 00671 f.bMagPhase=true; 00672 out.SetType(f); 00673 } 00674 00675 TData pos = 0.0; 00676 TData delta = out.GetSpectralRange() / 00677 ((TData)out.GetSize()-TData(1.0)); 00678 BPF &m1 = in1.GetMagBPF(); 00679 BPF &f1 = in1.GetPhaseBPF(); 00680 TData *m2 = in2.GetMagBuffer().GetPtr(); 00681 TData *f2 = in2.GetPhaseBuffer().GetPtr(); 00682 TData *mo = out.GetMagBuffer().GetPtr(); 00683 TData *fo = out.GetPhaseBuffer().GetPtr(); 00684 for (int i=0;i<mSize;i++) { 00685 mo[i]=TData(pow(10.0,m1.GetValue(pos)/10.0))*m2[i]; 00686 fo[i]=f1.GetValue(pos)+f2[i]; 00687 pos+=delta; 00688 } 00689 00690 f.bComplex=f.bPolar=f.bMagPhaseBPF=false; 00691 f.bMagPhase=true; 00692 out.SynchronizeTo(f); 00693 00694 if (remove2) { 00695 in2.RemoveMagBuffer(); 00696 in2.RemovePhaseBuffer(); 00697 in2.UpdateData(); 00698 } 00699 if (remove3) { 00700 out.RemoveMagBuffer(); 00701 out.RemovePhaseBuffer(); 00702 out.UpdateData(); 00703 } 00704 } 00705 00706 void SpectrumProduct::MultiplyBPFComplex(Spectrum& in1, Spectrum& in2, Spectrum& out) 00707 { 00708 switch(mScaleState) { 00709 case Slinlin: 00710 MultiplyBPFComplexLin(in1,in2,out); 00711 break; 00712 case Sloglog: 00713 MultiplyBPFComplexLog(in1,in2,out); 00714 break; 00715 case Slinlog: 00716 CLAM_ASSERT(false,"MultiplyBPFMagPhaseLinLog: Not implemented"); 00717 break; 00718 case Sloglin: 00719 MultiplyBPFComplexLogLin(in1,in2,out); 00720 break; 00721 } 00722 } 00723 void SpectrumProduct::MultiplyComplexBPF(Spectrum& in1, Spectrum& in2, Spectrum& out) 00724 { 00725 switch(mScaleState) { 00726 case Slinlin: 00727 MultiplyBPFComplexLin(in2,in1,out); 00728 break; 00729 case Sloglog: 00730 MultiplyBPFComplexLog(in2,in1,out); 00731 break; 00732 case Slinlog: 00733 MultiplyBPFComplexLogLin(in2,in1,out); 00734 break; 00735 case Sloglin: 00736 CLAM_ASSERT(false,"MultiplyBPFMagPhaseLinLog: Not implemented"); 00737 break; 00738 } 00739 } 00740 00741 void SpectrumProduct::MultiplyBPFComplexLin(Spectrum& in1, Spectrum& in2, Spectrum& out) 00742 { 00743 bool remove2=false,remove3=false; 00744 SpecTypeFlags f; 00745 00746 // This function was choosed because in1 is a BPF Spectrum, 00747 // and some of the non-BPF data objects have their Complex 00748 // attribute instantiated. We don't know which of them, 00749 // though, so we must check and instantiate the attribute it 00750 // it is missed. This could be optimised out by adding more 00751 // States, see coments on this in the class declaration. 00752 in2.GetType(f); 00753 if (!f.bComplex) { 00754 remove2=true; 00755 f.bComplex=true; 00756 in2.SetTypeSynchronize(f); 00757 } 00758 out.GetType(f); 00759 if (!f.bComplex) { 00760 remove3=true; 00761 f.bComplex=true; 00762 out.SetType(f); 00763 } 00764 00765 TData pos = 0.0; 00766 TData delta = out.GetSpectralRange() / 00767 ((TData)out.GetSize()-TData(1.0)); 00768 BPF &m1 = in1.GetMagBPF(); 00769 BPF &f1 = in1.GetPhaseBPF(); 00770 Complex *c2 = in2.GetComplexArray().GetPtr(); 00771 Complex *co = out.GetComplexArray().GetPtr(); 00772 for (int i=0;i<mSize;i++) { 00773 TData BRe = TData(fabs(m1.GetValue(pos)) * cos(f1.GetValue(pos))); 00774 TData BIm = TData(fabs(m1.GetValue(pos)) * sin(f1.GetValue(pos))); 00775 co[i]= Complex(BRe,BIm) * c2[i]; 00776 pos+=delta; 00777 } 00778 00779 f.bMagPhase=f.bPolar=f.bMagPhaseBPF=false; 00780 f.bComplex=true; 00781 out.SynchronizeTo(f); 00782 00783 if (remove2) { 00784 in2.RemoveComplexArray(); 00785 in2.UpdateData(); 00786 } 00787 if (remove3) { 00788 out.RemoveComplexArray(); 00789 out.UpdateData(); 00790 } 00791 } 00792 00793 // This is probably one of the most used methods, because it can be used 00794 // to apply a BPF filter in log scale to a linear complex spectrum, as the 00795 // one naturaly generated from a FFT 00796 void SpectrumProduct::MultiplyBPFComplexLogLin(Spectrum& in1, Spectrum& in2, Spectrum& out) 00797 { 00798 bool remove2=false,remove3=false; 00799 SpecTypeFlags f; 00800 00801 // This function was choosed because in1 is a BPF Spectrum, 00802 // and some of the non-BPF data objects have their Complex 00803 // attribute instantiated. We don't know which of them, 00804 // though, so we must check and instantiate the attribute it 00805 // it is missed. This could be optimised out by adding more 00806 // States, see coments on this in the class declaration. 00807 in2.GetType(f); 00808 if (!f.bComplex) { 00809 remove2=true; 00810 f.bComplex=true; 00811 in2.SetTypeSynchronize(f); 00812 } 00813 out.GetType(f); 00814 if (!f.bComplex) { 00815 remove3=true; 00816 f.bComplex=true; 00817 out.SetType(f); 00818 } 00819 00820 TData pos = 0.0; 00821 TData delta = out.GetSpectralRange() / 00822 ((TData)out.GetSize()-TData(1.0)); 00823 BPF &m1 = in1.GetMagBPF(); 00824 BPF &f1 = in1.GetPhaseBPF(); 00825 Complex *c2 = in2.GetComplexArray().GetPtr(); 00826 Complex *co = out.GetComplexArray().GetPtr(); 00827 for (int i=0;i<mSize;i++) { 00828 TData BRe = TData(pow(10.0,fabs(m1.GetValue(pos))/10.0) * cos(f1.GetValue(pos))); 00829 TData BIm = TData(pow(10.0,fabs(m1.GetValue(pos))/10.0) * sin(f1.GetValue(pos))); 00830 co[i]= Complex(BRe,BIm) * c2[i]; 00831 pos+=delta; 00832 } 00833 00834 f.bMagPhase=f.bPolar=f.bMagPhaseBPF=false; 00835 f.bComplex=true; 00836 out.SynchronizeTo(f); 00837 00838 if (remove2) { 00839 in2.RemoveComplexArray(); 00840 in2.UpdateData(); 00841 } 00842 if (remove3) { 00843 out.RemoveComplexArray(); 00844 out.UpdateData(); 00845 } 00846 } 00847 00848 00849 void SpectrumProduct::MultiplyBPFPolar(Spectrum& in1, Spectrum& in2, Spectrum& out) 00850 { 00851 switch(mScaleState) { 00852 case Slinlin: 00853 MultiplyBPFPolarLin(in1,in2,out); 00854 break; 00855 case Sloglog: 00856 MultiplyBPFPolarLog(in1,in2,out); 00857 break; 00858 case Slinlog: 00859 CLAM_ASSERT(false,"MultiplyBPFPolarLinLog: Not implemented"); 00860 break; 00861 case Sloglin: 00862 MultiplyBPFPolarLogLin(in1,in2,out); 00863 break; 00864 } 00865 } 00866 void SpectrumProduct::MultiplyPolarBPF(Spectrum& in1, Spectrum& in2, Spectrum& out) 00867 { 00868 switch(mScaleState) { 00869 case Slinlin: 00870 MultiplyBPFPolarLin(in2,in1,out); 00871 break; 00872 case Sloglog: 00873 MultiplyBPFPolarLog(in2,in1,out); 00874 break; 00875 case Slinlog: 00876 MultiplyBPFPolarLogLin(in2,in1,out); 00877 break; 00878 case Sloglin: 00879 CLAM_ASSERT(false,"MultiplyBPFPolarLinLog: Not implemented"); 00880 break; 00881 } 00882 } 00883 00884 void SpectrumProduct::MultiplyBPFPolarLin(Spectrum& in1, Spectrum& in2, Spectrum& out) 00885 { 00886 bool remove2=false,remove3=false; 00887 SpecTypeFlags f; 00888 00889 // This function was choosed because in1 is a BPF Spectrum, 00890 // and some of the non-BPF data objects have their Polar 00891 // attribute instantiated. We don't know which of them, 00892 // though, so we must check and instantiate the attribute it 00893 // it is missed. This could be optimised out by adding more 00894 // States, see coments on this in the class declaration. 00895 in2.GetType(f); 00896 if (!f.bPolar) { 00897 remove2=true; 00898 f.bPolar=true; 00899 in2.SetTypeSynchronize(f); 00900 } 00901 out.GetType(f); 00902 if (!f.bPolar) { 00903 remove3=true; 00904 f.bPolar=true; 00905 out.SetType(f); 00906 } 00907 00908 TData pos = 0.0; 00909 TData delta = out.GetSpectralRange() / 00910 ((TData)out.GetSize()-TData(1.0)); 00911 BPF &m1 = in1.GetMagBPF(); 00912 BPF &f1 = in1.GetPhaseBPF(); 00913 Polar *p2 = in2.GetPolarArray().GetPtr(); 00914 Polar *po = out.GetPolarArray().GetPtr(); 00915 for (int i=0;i<mSize;i++) { 00916 po[i]=Polar(m1.GetValue(pos),f1.GetValue(pos))*p2[i]; 00917 pos+=delta; 00918 } 00919 00920 f.bMagPhase=f.bComplex=f.bMagPhaseBPF=false; 00921 f.bPolar=true; 00922 out.SynchronizeTo(f); 00923 00924 if (remove2) { 00925 in2.RemovePolarArray(); 00926 in2.UpdateData(); 00927 } 00928 if (remove3) { 00929 out.RemovePolarArray(); 00930 out.UpdateData(); 00931 } 00932 } 00933 00934 void SpectrumProduct::MultiplyBPFPolarLogLin(Spectrum& in1, Spectrum& in2, Spectrum& out) 00935 { 00936 bool remove2=false,remove3=false; 00937 SpecTypeFlags f; 00938 00939 // This function was choosed because in1 is a BPF Spectrum, 00940 // and some of the non-BPF data objects have their Polar 00941 // attribute instantiated. We don't know which of them, 00942 // though, so we must check and instantiate the attribute it 00943 // it is missed. This could be optimised out by adding more 00944 // States, see coments on this in the class declaration. 00945 in2.GetType(f); 00946 if (!f.bPolar) { 00947 remove2=true; 00948 f.bPolar=true; 00949 in2.SetTypeSynchronize(f); 00950 } 00951 out.GetType(f); 00952 if (!f.bPolar) { 00953 remove3=true; 00954 f.bPolar=true; 00955 out.SetType(f); 00956 } 00957 00958 TData pos = 0.0; 00959 TData delta = out.GetSpectralRange() / 00960 ((TData)out.GetSize()-TData(1.0)); 00961 BPF &m1 = in1.GetMagBPF(); 00962 BPF &f1 = in1.GetPhaseBPF(); 00963 Polar *p2 = in2.GetPolarArray().GetPtr(); 00964 Polar *po = out.GetPolarArray().GetPtr(); 00965 for (int i=0;i<mSize;i++) { 00966 TData BMag = TData(pow(10.0,m1.GetValue(pos)/10.0)); 00967 TData BPha = f1.GetValue(pos); 00968 po[i]=Polar(BMag,BPha)*p2[i]; 00969 pos+=delta; 00970 } 00971 00972 f.bMagPhase=f.bComplex=f.bMagPhaseBPF=false; 00973 f.bPolar=true; 00974 out.SynchronizeTo(f); 00975 00976 if (remove2) { 00977 in2.RemovePolarArray(); 00978 in2.UpdateData(); 00979 } 00980 if (remove3) { 00981 out.RemovePolarArray(); 00982 out.UpdateData(); 00983 } 00984 } 00985 00986 void SpectrumProduct::MultiplyBPF(Spectrum& in1, Spectrum& in2, Spectrum& out) 00987 { 00988 // First we check if the abcisas agree 00989 CLAM_ASSERT(false,"MultiplyBPF: method not implemented"); 00990 for (int i=0;i<mSize;i++) { 00991 PointTmpl<TData,TData> &pm1=in1.GetMagBPF().GetPointArray()[i]; 00992 PointTmpl<TData,TData> &pm2=in2.GetMagBPF().GetPointArray()[i]; 00993 PointTmpl<TData,TData> &pmo=out.GetMagBPF().GetPointArray()[i]; 00994 PointTmpl<TData,TData> &pf1=in1.GetPhaseBPF().GetPointArray()[i]; 00995 PointTmpl<TData,TData> &pf2=in2.GetPhaseBPF().GetPointArray()[i]; 00996 PointTmpl<TData,TData> &pfo=out.GetPhaseBPF().GetPointArray()[i]; 00997 CLAM_ASSERT(pm1.GetX() == pm2.GetX(), 00998 "MultiplyBPF: input BPF abcisas do not match " 00999 "(and BPF merging not yet iplemented)"); 01000 CLAM_ASSERT(pm1.GetX() == pmo.GetX(), 01001 "MultiplyBPF: output BPF abcisas do not match " 01002 "(and BPF merging not yet iplemented)"); 01003 pmo.SetY(pm1.GetY()*pm2.GetY()); 01004 pfo.SetY(pf1.GetY()+pf2.GetY()); 01005 } 01006 01007 } 01008 01009 void SpectrumProduct::MultiplyMagPhaseLog(Spectrum& in1, Spectrum& in2, Spectrum& out) 01010 { 01011 CLAM_ASSERT(false,"MultiplyMagPhaseLog: Not implemented"); 01012 } 01013 void SpectrumProduct::MultiplyMagPhaseLinLog(Spectrum& in1, Spectrum& in2, Spectrum& out) 01014 { 01015 CLAM_ASSERT(false,"MultiplyMagPhaseLinLog: Not implemented"); 01016 } 01017 void SpectrumProduct::MultiplyComplexLog(Spectrum& in1, Spectrum& in2, Spectrum& out) 01018 { 01019 CLAM_ASSERT(false,"MultiplyComplexLog: Not implemented"); 01020 } 01021 void SpectrumProduct::MultiplyComplexLinLog(Spectrum& in1, Spectrum& in2, Spectrum& out) 01022 { 01023 CLAM_ASSERT(false,"MultiplyComplexLinLog: Not implemented"); 01024 } 01025 void SpectrumProduct::MultiplyPolarLog(Spectrum& in1, Spectrum& in2, Spectrum& out) 01026 { 01027 CLAM_ASSERT(false,"MultiplyPolarLog: Not implemented"); 01028 } 01029 void SpectrumProduct::MultiplyPolarLinLog(Spectrum& in1, Spectrum& in2, Spectrum& out) 01030 { 01031 CLAM_ASSERT(false,"MultiplyPolarLinLog: Not implemented"); 01032 } 01033 void SpectrumProduct::MultiplyBPFComplexLog(Spectrum& in1, Spectrum& in2, Spectrum& out) 01034 { 01035 CLAM_ASSERT(false,"MultiplyBPFComplexLog: Not implemented"); 01036 } 01037 void SpectrumProduct::MultiplyBPFComplexLinLog(Spectrum& in1, Spectrum& in2, Spectrum& out) 01038 { 01039 CLAM_ASSERT(false,"MultiplyBPFComplexLinLog: Not implemented"); 01040 } 01041 void SpectrumProduct::MultiplyBPFPolarLog(Spectrum& in1, Spectrum& in2, Spectrum& out) 01042 { 01043 CLAM_ASSERT(false,"MultiplyBPFPolarLog: Not implemented"); 01044 } 01045 void SpectrumProduct::MultiplyBPFPolarLinLog(Spectrum& in1, Spectrum& in2, Spectrum& out) 01046 { 01047 CLAM_ASSERT(false,"MultiplyBPFPolarLinLog: Not implemented"); 01048 } 01049 void SpectrumProduct::MultiplyBPFMagPhaseLog(Spectrum& in1, Spectrum& in2, Spectrum& out) 01050 { 01051 CLAM_ASSERT(false,"MultiplyBPFMagPhaseLog: Not implemented"); 01052 } 01053 void SpectrumProduct::MultiplyBPFMagPhaseLinLog(Spectrum& in1, Spectrum& in2, Spectrum& out) 01054 { 01055 CLAM_ASSERT(false,"MultiplyBPFMagPhaseLinLog: Not implemented"); 01056 } 01057 } 01058