SpectrumAdder.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 "SpectrumAdder.hxx"
00024 #include "SpectrumConfig.hxx"
00025 
00026 #include <sstream>
00027 
00028 namespace CLAM {
00029 
00030         void SpecAdderConfig::DefaultInit()
00031         {
00032                 AddNInputs();
00033                 UpdateData();
00034                 SetNInputs(0);
00035         }
00036 
00037 
00038         SpectrumAdder::SpectrumAdder()
00039                 : mSize(0),
00040                   mInputs(0),
00041                   complex_bufs(0),polar_bufs(0),mag_bufs(0),phase_bufs(0),
00042                   remove(0),
00043                   mOut("Output",this),
00044                   mProtoState(SOther)
00045         {
00046                 Configure(SpecAdderConfig());
00047         }
00048 
00049         SpectrumAdder::SpectrumAdder(const SpecAdderConfig &c)
00050                 : mSize(0),
00051                   mInputs(0),
00052                   complex_bufs(0),polar_bufs(0),mag_bufs(0),phase_bufs(0),
00053                   remove(0),
00054                   mOut("Output",this),
00055                   mProtoState(SOther)
00056         {
00057                 Configure(c);
00058         }
00059 
00060         std::string SpectrumAdder::NewUniqueName()
00061         {
00062                 static int ObjectCount=0;
00063 
00064                 std::stringstream name;
00065 
00066                 name << "SpectrumAdder_" << ObjectCount++;
00067 
00068                 return name.str();
00069         }
00070 
00071         bool SpectrumAdder::ConcreteConfigure(const ProcessingConfig&c)
00072         {
00073                 int oldNInputs;
00074 
00075                 // Nothing specific to configure here...
00076                 if (mConfig.HasNInputs())
00077                         oldNInputs = mConfig.GetNInputs();
00078                 else
00079                         oldNInputs = 0;
00080 
00081                 CopyAsConcreteConfig(mConfig, c);
00082                 if ( !mConfig.HasNInputs() ||
00083                          mConfig.GetNInputs() <= 0 ) {
00084                         mNInputs = 0;
00085                         return false;
00086                 }
00087                         
00088                 mNInputs = mConfig.GetNInputs();
00089 
00090                 if (mNInputs == oldNInputs)
00091                         return true;
00092 
00093 
00094                 if (mInputs)
00095                         delete(mInputs);
00096 
00097                 if (complex_bufs) {
00098                         delete(complex_bufs);
00099                         complex_bufs=0;
00100                 }
00101                 if (polar_bufs) {
00102                         delete(polar_bufs);
00103                         polar_bufs=0;
00104                 }
00105                 if (mag_bufs) {
00106                         delete(mag_bufs);
00107                         mag_bufs=0;
00108                 }
00109                 if (phase_bufs) {
00110                         delete(phase_bufs);
00111                         phase_bufs=0;
00112                 }
00113                 if (remove) {
00114                         delete(remove);
00115                         remove=0;
00116                 }
00117 
00118                 mInputs = new InPort<Spectrum>*[mNInputs];
00119                 complex_bufs = new Complex*[mNInputs];
00120                 polar_bufs = new Polar*[mNInputs];
00121                 mag_bufs = new TData*[mNInputs];
00122                 phase_bufs = new TData*[mNInputs];
00123                 remove = new bool[mNInputs];
00124 
00125                 for (int i=0; i<mNInputs; i++) {
00126                         std::stringstream name;
00127                         name << "Input " << i;
00128                         mInputs[i]=new InPort<Spectrum>(name.str(),this);
00129                 }
00130 
00131                 return true;
00132         }
00133 
00134         SpectrumAdder::~SpectrumAdder()
00135         {
00136                 if (mInputs)
00137                         delete(mInputs);
00138 
00139                 if (complex_bufs) {
00140                         delete(complex_bufs);
00141                         complex_bufs=0;
00142                 }
00143                 if (polar_bufs) {
00144                         delete(polar_bufs);
00145                         polar_bufs=0;
00146                 }
00147                 if (mag_bufs) {
00148                         delete(mag_bufs);
00149                         mag_bufs=0;
00150                 }
00151                 if (phase_bufs) {
00152                         delete(phase_bufs);
00153                         phase_bufs=0;
00154                 }
00155                 if (remove) {
00156                         delete(remove);
00157                         remove=0;
00158                 }
00159         }
00160 
00161 
00162         // Unsupervised Do() function.
00163         bool SpectrumAdder::Do(Spectrum **inputs, Spectrum& out)
00164         {
00165                 CLAM_DEBUG_ASSERT( IsRunning(),
00166                         "SpectrumAdder::Do(): Not in execution mode");
00167 
00168                 switch (mProtoState) {
00169                 // Fast prototype configurations
00170                 case SMagPhase:
00171                         AddMagPhase(inputs,out);
00172                         break;
00173                 case SComplex:
00174                         AddComplex(inputs,out);
00175                         break;
00176                 case SPolar:
00177                         AddPolar(inputs,out);
00178                         break;
00179                 case ShasBPF:
00180                         CLAM_ASSERT(false,"SpectrumAdder::Do(): BPF addition not implemented");
00181                         break;
00182                 // Slow type configurations
00183                 case SOther:
00184                         Add(inputs,out);
00185                         break;
00186                 default:
00187                         CLAM_ASSERT(false,"Do(...) : internal inconsistency (invalid mProtoState)");
00188                 }
00189 
00190                 return true;
00191         }
00192 
00193         bool SpectrumAdder::Do(void)
00194         {
00195                 CLAM_ASSERT(false,"SpectrumAdder::Do(): Not implemented");
00196         }
00197 
00198         // This function analyses the inputs and decides which prototypes to use 
00199         // For the sum computation. 
00200         bool SpectrumAdder::SetPrototypes(Spectrum **inputs,const Spectrum& out)
00201         {
00202                 CLAM_ASSERT(IsConfigured(),
00203                             "SpectrumAdder::SetPrototypes(): Not configured");
00204                 CLAM_ASSERT(mNInputs > 0,
00205                             "SpectrumAdder::SetPrototypes(): Inconsistent mNInputs");
00206 
00207                 // Check common attributes
00208                 SpectrumConfig *si = new SpectrumConfig[mNInputs];
00209                 SpectrumConfig so;
00210                 SpecTypeFlags *ti = new SpecTypeFlags[mNInputs];
00211                 SpecTypeFlags to;
00212 
00213                 for (int i=0; i<mNInputs; i++) {
00214                         inputs[i]->GetConfig(si[i]);
00215                         inputs[i]->GetType(ti[i]);
00216                 }
00217                 out.GetConfig(so);
00218                 out.GetType(to);
00219 
00220 
00221                 // Do we have the necesary attributes?
00222                 CLAM_BEGIN_CHECK
00223                         for (int i=0;i<mNInputs; i++)
00224                                 CLAM_ASSERT(ti[i].bMagPhase || ti[i].bComplex || ti[i].bPolar,
00225                                         "SpectrumAdders: Output spectrum object with no non-BPF attributes");
00226                         CLAM_ASSERT(to.bMagPhase || to.bComplex || to.bPolar,
00227                                 "SpectrumAdders: Output spectrum object with no non-BPF attributes");
00228                         // We check that the size, the spectral range and the scale of the arrays all match.
00229                         CLAM_ASSERT(so.GetSize(), "SpectrumAdder::SetPrototypes: Zero size spectrum output");
00230                 CLAM_END_CHECK
00231 
00232                 mSize=so.GetSize();
00233                 TData range = so.GetSpectralRange();
00234                 EScale scale = so.GetScale();
00235 
00236                 CLAM_BEGIN_CHECK
00237                 for (int i=0; i<mNInputs; i++) {
00238                         CLAM_ASSERT(mSize == si[i].GetSize(),
00239                                 "SpectrumAdder::SetPrototypes: Size mismatch in spectrum sum");
00240                         CLAM_ASSERT(range == si[i].GetSpectralRange(),
00241                                 "SpectrumAdder::SetPrototypes: Spectral range mismatch in spectrum sum");
00242                         CLAM_ASSERT(scale == si[i].GetScale(),
00243                                 "SpectrumAdder::SetPrototypes: Scale mismatch in spectrum sum");
00244                 }
00245                 CLAM_END_CHECK
00246 
00247                 if (scale == EScale::eLinear)
00248                         mScaleState=Slin;
00249                 else
00250                         mScaleState=Slog;
00251 
00252                 // Prototypes.
00253 
00254                 // We first count how many inputs have each type of attribute
00255                 // instantiated.
00256                 int Ncomplex=0,Npolar=0,Nmagphase=0;
00257                 for (int i=0; i<mNInputs;i++) {
00258                         if (ti[i].bMagPhase)
00259                                 Nmagphase++;
00260                         if (ti[i].bComplex)
00261                                 Ncomplex++;
00262                         if (ti[i].bPolar)
00263                                 Npolar++;
00264                 }
00265                 if (to.bMagPhase)
00266                         Nmagphase++;
00267                 if (to.bComplex)
00268                         Ncomplex++;
00269                 if (to.bPolar)
00270                         Npolar++;
00271 
00272                 // Now we look for the best choice.
00273                 for (int i=mNInputs+1; i>0; i--) {
00274                         if (Nmagphase == i) {
00275                                 mProtoState=SMagPhase;
00276                                 return true;
00277                         }
00278                         if (Ncomplex == i) {
00279                                 mProtoState=SComplex;
00280                                 return true;
00281                         }
00282                         if (Npolar == i) {
00283                                 mProtoState=SPolar;
00284                                 return true;
00285                         }
00286                 }
00287                 CLAM_ASSERT(false,"SpectrumAdder::SetPrototypes: Prototype inconsistency");
00288         }
00289 
00290 
00291         bool SpectrumAdder::SetPrototypes()
00292         {
00293                 CLAM_ASSERT(false,"SpectrumAdder::SetPrototypes(): Not implemented");
00294         }
00295 
00296         bool SpectrumAdder::UnsetPrototypes()
00297         {
00298                 mProtoState=SOther;
00299                 return true;
00300         }
00301 
00302 
00303         void SpectrumAdder::Add(Spectrum **inputs, Spectrum& out)
00304         {
00305                 PrototypeState state_copy = mProtoState;
00306                 ScaleState state2_copy = mScaleState;
00307 
00308                 SetPrototypes(inputs,out);
00309                 Do(inputs,out);
00310                 
00311                 mProtoState = state_copy;
00312                 mScaleState = state2_copy;
00313         }
00314 
00315 
00316         void SpectrumAdder::AddMagPhase(Spectrum **inputs, Spectrum& out)
00317         {
00318                 switch(mScaleState) {
00319                 case Slin:
00320                         AddMagPhaseLin(inputs,out);
00321                         break;
00322                 case Slog:
00323                         AddMagPhaseLog(inputs,out);
00324                         break;
00325                 }
00326         }
00327 
00328         void SpectrumAdder::AddMagPhaseLin(Spectrum **inputs, Spectrum& out)
00329         {
00330                 bool removeo=false;
00331                 SpecTypeFlags f;
00332                 int i;
00333 
00334                 // This function was choosed because some of the data objects had
00335                 // their MagPhase attribute instantiated. We don't know which of
00336                 // them, though, so we must check and instantiate the attribute
00337                 // if it is missing.
00338                 for (i=0;i<mNInputs; i++) {
00339                         inputs[i]->GetType(f);
00340                         if (!f.bMagPhase) {
00341                                 remove[i]=true;
00342                                 f.bMagPhase=true;
00343                                 inputs[i]->SetTypeSynchronize(f);
00344                         }
00345                         else
00346                                 remove[i]=false;
00347                         mag_bufs[i] = inputs[i]->GetMagBuffer().GetPtr();
00348                         phase_bufs[i] = inputs[i]->GetPhaseBuffer().GetPtr();
00349                         
00350                 }
00351                 out.GetType(f);
00352                 if (!f.bMagPhase) {
00353                         removeo=true;
00354                         f.bMagPhase=true;
00355                         out.SetType(f);
00356                 }
00357                 TData *mo = out.GetMagBuffer().GetPtr();
00358                 TData *fo = out.GetPhaseBuffer().GetPtr();
00359 
00360                 for (int s=0;s<mSize; s++) {
00361                         TData re=0.0,im=0.0;
00362                         for (i=0;i<mNInputs; i++) {
00363                                 re+=mag_bufs[i][s]*TData(cos(phase_bufs[i][s]));
00364                                 im+=mag_bufs[i][s]*TData(sin(phase_bufs[i][s]));
00365                         }
00366                         mo[s]=TData(sqrt(re*re+im*im));
00367                         fo[s]=TData(atan2(im,re));
00368                 }
00369 
00370                 f.bComplex=f.bPolar=f.bMagPhaseBPF=false;
00371                 f.bMagPhase=true;
00372                 out.SynchronizeTo(f);
00373 
00374                 for (i=0; i<mNInputs; i++)
00375                         if (remove[i]) {
00376                                 inputs[i]->RemoveMagBuffer();
00377                                 inputs[i]->RemovePhaseBuffer();
00378                                 inputs[i]->UpdateData();
00379                         }
00380                 if (removeo) {
00381                         out.RemoveMagBuffer();
00382                         out.RemovePhaseBuffer();
00383                         out.UpdateData();
00384                 }
00385 
00386         }
00387 
00388         void SpectrumAdder::AddComplex(Spectrum **inputs, Spectrum& out)
00389         {
00390                 switch(mScaleState) {
00391                 case Slin:
00392                         AddComplexLin(inputs,out);
00393                         break;
00394                 case Slog:
00395                         AddComplexLog(inputs,out);
00396                         break;
00397                 }
00398         }
00399 
00400         void SpectrumAdder::AddComplexLin(Spectrum **inputs, Spectrum& out)
00401         {
00402                 bool removeo=false;
00403                 SpecTypeFlags f;
00404                 int i;
00405 
00406                 // This function was choosed because some of the data objects had
00407                 // their Complex attribute instantiated. We don't know which of
00408                 // them, though, so we must check and instantiate the attribute
00409                 // it it is missed. This could be optimised out by adding more
00410                 // States, see coments on this in the class declaration.
00411                 for (i=0;i<mNInputs; i++) {
00412                         inputs[i]->GetType(f);
00413                         if (!f.bComplex) {
00414                                 remove[i]=true;
00415                                 f.bComplex=true;
00416                                 inputs[i]->SetTypeSynchronize(f);
00417                         }
00418                         else
00419                                 remove[i]=false;
00420                         complex_bufs[i] = inputs[i]->GetComplexArray().GetPtr();
00421                         
00422                 }
00423                 out.GetType(f);
00424                 if (!f.bComplex) {
00425                         removeo=true;
00426                         f.bComplex=true;
00427                         out.SetType(f);
00428                 }
00429                 Complex *co = out.GetComplexArray().GetPtr();
00430 
00431                 for (int s=0;s<mSize;s++) {
00432                         co[s]=0;
00433                         for (i=0;i<mNInputs; i++)
00434                                 co[s]+=complex_bufs[i][s];
00435                 }
00436 
00437                 f.bMagPhase=f.bPolar=f.bMagPhaseBPF=false;
00438                 f.bComplex=true;
00439                 out.SynchronizeTo(f);
00440 
00441                 for (i=0; i<mNInputs; i++)
00442                         if (remove[i]) {
00443                                 inputs[i]->RemoveComplexArray();
00444                                 inputs[i]->UpdateData();
00445                         }
00446                 if (removeo) {
00447                         out.RemoveComplexArray();
00448                         out.UpdateData();
00449                 }
00450         }
00451 
00452 
00453         void SpectrumAdder::AddPolar(Spectrum **inputs, Spectrum& out)
00454         {
00455                 switch(mScaleState) {
00456                 case Slin:
00457                         AddPolarLin(inputs,out);
00458                         break;
00459                 case Slog:
00460                         AddPolarLog(inputs,out);
00461                         break;
00462                 }
00463         }
00464 
00465         void SpectrumAdder::AddPolarLin(Spectrum **inputs, Spectrum& out)
00466         {
00467                 bool removeo=false;
00468                 SpecTypeFlags f;
00469                 int i;
00470                 
00471                 // This function was choosed because some of the data objects had
00472                 // their Polar attribute instantiated. We don't know which of
00473                 // them, though, so we must check and instantiate the attribute
00474                 // it it is missed. This could be optimised out by adding more
00475                 // States, see coments on this in the class declaration.
00476                 for (i=0;i<mNInputs; i++) {
00477                         inputs[i]->GetType(f);
00478                         if (!f.bPolar) {
00479                                 remove[i]=true;
00480                                 f.bPolar=true;
00481                                 inputs[i]->SetTypeSynchronize(f);
00482                         }
00483                         else
00484                                 remove[i]=false;
00485                         polar_bufs[i] = inputs[i]->GetPolarArray().GetPtr();
00486                         
00487                 }
00488                 out.GetType(f);
00489                 if (!f.bPolar) {
00490                         removeo=true;
00491                         f.bPolar=true;
00492                         out.SetType(f);
00493                 }
00494 
00495                 Polar *po = out.GetPolarArray().GetPtr();
00496                 for (int s=0;s<mSize;s++) {
00497                         po[s]=Polar(0.0,0.0);
00498                         for (i=0;i<mNInputs;i++)
00499                                 po[s]+=polar_bufs[i][s];
00500                 }
00501 
00502                 f.bComplex=f.bMagPhase=f.bMagPhaseBPF=false;
00503                 f.bPolar=true;
00504                 out.SynchronizeTo(f);
00505 
00506                 for (i=0; i<mNInputs; i++)
00507                         if (remove[i]) {
00508                                 inputs[i]->RemovePolarArray();
00509                                 inputs[i]->UpdateData();
00510                         }
00511                 if (removeo) {
00512                         out.RemovePolarArray();
00513                         out.UpdateData();
00514                 }
00515         }
00516 
00517 
00518         // UNINMPLEMENTED METHODS. Some day...
00519         void SpectrumAdder::AddMagPhaseLog(Spectrum **inputs, Spectrum& out)
00520         {
00521                 CLAM_ASSERT(false,"AddMagPhaseLog: Not implemented");
00522         }
00523         void SpectrumAdder::AddComplexLog(Spectrum **inputs, Spectrum& out)
00524         {
00525                 CLAM_ASSERT(false,"AddComplexLog: Not implemented");
00526         }
00527         void SpectrumAdder::AddPolarLog(Spectrum **inputs, Spectrum& out)
00528         {
00529                 CLAM_ASSERT(false,"AddPolarLog: Not implemented");
00530         }
00531 }
00532 
Generated by  doxygen 1.6.3