SpectrumProduct.cxx

Go to the documentation of this file.
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                         Point &pm1=in1.GetMagBPF().GetPointArray()[i];
00992                         Point &pm2=in2.GetMagBPF().GetPointArray()[i];
00993                         Point &pmo=out.GetMagBPF().GetPointArray()[i];
00994                         Point &pf1=in1.GetPhaseBPF().GetPointArray()[i];
00995                         Point &pf2=in2.GetPhaseBPF().GetPointArray()[i];
00996                         Point &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 
Generated by  doxygen 1.6.3