SpectralDescriptors.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 "SpectralDescriptors.hxx"
00023 #include "Spectrum.hxx"
00024 #include "Array.hxx"
00025 #include <algorithm>
00026 
00027 namespace CLAM{
00028         
00029 DataArray       Add(DataArray &a, DataArray &b) {
00030         TIndex i;
00031         TSize sizea=a.Size(); 
00032         TSize sizeb=b.Size();
00033         TSize size;
00034         DataArray result;
00035         
00036         // One has size==0 (optimized with respect to the following case?)
00037         if (sizea==0) {
00038                 result=b;
00039                 return result;
00040         }
00041         if (sizeb==0) {
00042                 result=a;
00043                 return result;
00044         }
00045         
00046         // Different sizes
00047         if(sizea != sizeb) {
00048                 if (sizea < sizeb) {
00049                         size=sizeb;
00050                         result.Resize(size);
00051                         result.SetSize(size);
00052                         for (i=0; i<sizea; i++)
00053                                 result[i]=a[i]+b[i];
00054                         for (i=sizea; i<sizeb; i++)
00055                                 result[i]=b[i];
00056                         return result;
00057                 }
00058                 else {  // sizea>sizeb
00059                         size=sizea;
00060                         result.Resize(size);
00061                         result.SetSize(size);
00062                         for (i=0; i<sizeb; i++)
00063                                 result[i]=a[i]+b[i];
00064                         for (i=sizeb; i<sizea; i++)
00065                                 result[i]=a[i];
00066                         return result;
00067                 }
00068         }
00069         // Equal size
00070         size=sizea;
00071         result.Resize(size);
00072         result.SetSize(size);
00073         for (i=0; i<size; i++)
00074                 result[i]=a[i]+b[i];
00075         return result;
00076 }
00077 
00078 DataArray Multiply(TData &factor, DataArray &a) {
00079         TIndex i;
00080         TSize size=a.Size(); 
00081         DataArray result;
00082         result.Resize(size);
00083         result.SetSize(size);
00084         for (i=0; i<size; i++)
00085                 result[i]=factor*a[i];
00086         return result;
00087 }
00088 
00089 /* Scalar product of two vectors */
00090 DataArray Multiply(DataArray &a, DataArray &b) {
00091         TIndex i;
00092         TSize size=a.Size(); 
00093         DataArray result;
00094         result.Resize(size);
00095         result.SetSize(size);
00096         for (i=0; i<size; i++)
00097                 result[i]=a[i]*b[i];
00098         return result;
00099 }
00100 
00101 SpectralDescriptors::SpectralDescriptors(Spectrum* pSpectrum):Descriptor(eNumAttr)
00102 {
00103         CLAM_ASSERT(pSpectrum->GetScale()==EScale::eLinear,
00104                 "Spectral Descriptors require a linear magnitude Spectrum");
00105         MandatoryInit();
00106         mpSpectrum=pSpectrum;
00107 }
00108 
00109 SpectralDescriptors::SpectralDescriptors(TData initVal):Descriptor(eNumAttr)
00110 {
00111         MandatoryInit();
00112         AddAll();
00113         UpdateData();
00114         SetMean(initVal);
00115         SetGeometricMean(initVal);
00116         SetEnergy(initVal);
00117         SetCentroid(initVal);
00118         SetMoment2(initVal);
00119         SetMoment3(initVal);    
00120         SetMoment4(initVal);
00121         SetMoment5(initVal);
00122         SetMoment6(initVal);
00123         SetSpread(initVal);
00124         SetMagnitudeSkewness(initVal);
00125         SetMagnitudeKurtosis(initVal);
00126         SetFlatness(initVal);
00127         SetHighFrequencyContent(initVal);
00128         SetMaxMagFreq(initVal);
00129         SetLowFreqEnergyRelation(initVal);
00130         SetRolloff(initVal);
00131         SetSlope(initVal);
00132 }
00133 
00134 void SpectralDescriptors::DefaultInit() {
00135         mpSpectrum=0;
00136         mpStats=0;
00137         //Warning: no attributes are added by default, the user is in charge of adding the ones he is interested in
00138 }
00139 
00140 void SpectralDescriptors::CopyInit(const SpectralDescriptors & copied) 
00141 {
00142         mpSpectrum=copied.mpSpectrum;
00143         mpStats=0;
00144 }
00145 
00146 const Spectrum* SpectralDescriptors::GetpSpectrum() const 
00147 {
00148         return mpSpectrum;
00149 }
00150 
00151 void SpectralDescriptors::SetpSpectrum(Spectrum* pSpectrum) 
00152 {
00153         
00154         CLAM_ASSERT(pSpectrum->GetScale()==EScale::eLinear,
00155                 "Spectral Descriptors require a linear magnitude Spectrum");
00156         mpSpectrum=pSpectrum;
00157         //TODO: we are asuming Spectrum is in MagBuffer
00158         //TODO: it may give problems because pointer passed
00159         InitStats(&mpSpectrum->GetMagBuffer());
00160 
00161         mDeltaFreq=double(mpSpectrum->GetSpectralRange())/(mpSpectrum->GetSize()-1);
00162         
00163 }
00164 
00165 void SpectralDescriptors::ConcreteCompute()
00166 {
00167         if (HasMean())
00168                 SetMean(mpStats->GetMean());
00169         if (HasGeometricMean())
00170         {
00171                 CLAM_ASSERT( mpSpectrum->GetScale() == CLAM::EScale::eLinear,
00172                              "The Geometric Mean, as implemented in CLAM, can only"
00173                              " be computed over Linear Spectral Power distirbutions");
00174                 SetGeometricMean(mpStats->GetGeometricMean());
00175         }
00176         if (HasEnergy())
00177                 SetEnergy(mpStats->GetEnergy());
00178         if (HasCentroid())
00179                 SetCentroid(mpStats->GetCentroid()*mDeltaFreq);
00180         if(HasMoment2())
00181                 SetMoment2(mpStats->GetMoment(SecondOrder));
00182         if(HasMoment3())
00183                 SetMoment3(mpStats->GetMoment(ThirdOrder));     
00184         if(HasMoment4())
00185                 SetMoment4(mpStats->GetMoment(FourthOrder));
00186         if(HasMoment5())
00187                 SetMoment5(mpStats->GetMoment(FifthOrder));
00188         if(HasMoment6())
00189                 SetMoment6(mpStats->GetMoment((O<6>*)(0)));
00190         if (HasSpread())
00191                 SetSpread(mpStats->GetSpread()*mDeltaFreq*mDeltaFreq);
00192         if(HasMagnitudeSkewness())
00193                 SetMagnitudeSkewness(mpStats->GetSkew());
00194         if(HasMagnitudeKurtosis())      
00195                 SetMagnitudeKurtosis(mpStats->GetKurtosis());
00196         if(HasFlatness())
00197                 SetFlatness(ComputeSpectralFlatness());
00198         if(HasHighFrequencyContent())
00199                 SetHighFrequencyContent(ComputeHighFrequencyContent());
00200         if(HasMaxMagFreq())
00201                 SetMaxMagFreq(ComputeMaxMagFreq());
00202         if(HasLowFreqEnergyRelation())
00203                 SetLowFreqEnergyRelation(ComputeLowFreqEnergyRelation());
00204         if(HasRolloff())
00205                 SetRolloff(ComputeRolloff());
00206         if(HasSlope())
00207                 SetSlope(mpStats->GetSlope()/mDeltaFreq);
00208 }
00209 
00210 
00211 /*this has been mostly copied and pasted from cuidado and should be checked and some of
00212 it promoted into basicOps*/
00213 TData SpectralDescriptors::ComputeSpectralFlatness()
00214 {
00215         return mpStats->GetFlatness();
00216 }
00217 
00218 /*this has been mostly copied and pasted from cuidado and should be checked and some of
00219 it promoted into basicOps*/
00220 TData SpectralDescriptors::ComputeHighFrequencyContent()
00221 {
00222         const DataArray & mag = mpSpectrum->GetMagBuffer();
00223         const TSize size=mpSpectrum->GetSize();
00224         double temp = 0.0;
00225         for (int i=1;i<size;i++)
00226                 temp += mag[i]*mag[i]*i;
00227         return temp;
00228         /*
00229         return WeightedPoweredSum<2>()(mpSpectrum->GetMagBuffer());
00230         */ 
00231 }
00232 
00241 TData SpectralDescriptors::ComputeMaxMagFreq()
00242 { 
00243         // Zero is not enough for spectrums in dB's
00244         TData max = -1000.0;
00245         TIndex index = -1;
00246         
00247         const DataArray& data=mpSpectrum->GetMagBuffer();
00248         const unsigned size=mpSpectrum->GetSize();
00249         for(unsigned i=0; i<size; i++) 
00250                 if(data[i] > max )
00251                 {
00252                         max = data[i];
00253                         index = i;
00254                 } 
00255 
00256         // Convert from index to frequency value in Hz
00257         return (TData) index * mDeltaFreq;
00258 }
00259 
00260 /*this has been mostly copied and pasted from cuidado and should be checked and some of
00261 it promoted into basicOps*/
00262 TData SpectralDescriptors::ComputeLowFreqEnergyRelation() 
00263 { 
00264         // Energy(0-100 Hz) / Total Energy
00265         TIndex index = Round(100.0/mDeltaFreq);
00266         const DataArray & magnitudeBuffer = mpSpectrum->GetMagBuffer();
00267         const DataArray data(const_cast<TData*>(magnitudeBuffer.GetPtr()), index);
00268 
00269         Energy energyComputer;
00270         TData totalEnergy = mpStats->GetEnergy();
00271         if (totalEnergy < 10e-4) totalEnergy=10e-4;
00272 
00273         TData result=(energyComputer(data)/totalEnergy );
00274         return result;
00275 }
00276 
00277 TData SpectralDescriptors::ComputeRolloff() 
00278 { 
00279         DataArray& mags     = mpSpectrum->GetMagBuffer();
00280         TSize      magsSize = mpSpectrum->GetSize();
00281 
00282         TData eThreshold = 0.85 * mpStats->GetEnergy();
00283         TData cumEnergy  = 0;
00284         for (TIndex i=0; i<magsSize; i++)
00285         {
00286                 cumEnergy += mags[i]*mags[i];
00287                 if (cumEnergy <= eThreshold) continue;
00288                 return i * mDeltaFreq;
00289         }
00290         return 0.0;
00291 }
00292 
00293 
00294 SpectralDescriptors operator * (const SpectralDescriptors& a,TData mult)
00295 {
00296         SpectralDescriptors  tmpD(a);
00297         if(a.HasMean())
00298                 tmpD.SetMean(a.GetMean()*mult);
00299         if(a.HasGeometricMean())
00300                 tmpD.SetGeometricMean(a.GetGeometricMean()*mult);
00301         if(a.HasEnergy())
00302                 tmpD.SetEnergy(a.GetEnergy()*mult);
00303         if(a.HasCentroid())
00304                 tmpD.SetCentroid(a.GetCentroid()*mult);
00305         if(a.HasMoment2())
00306                 tmpD.SetMoment2(a.GetMoment2()*mult);
00307         if(a.HasMoment3())
00308                 tmpD.SetMoment3(a.GetMoment3()*mult);
00309         if(a.HasMoment4())
00310                 tmpD.SetMoment4(a.GetMoment4()*mult);
00311         if(a.HasMoment5())
00312                 tmpD.SetMoment5(a.GetMoment5()*mult);
00313         if(a.HasMoment6())
00314                 tmpD.SetMoment6(a.GetMoment6()*mult);
00315         if(a.HasFlatness())
00316                 tmpD.SetFlatness(a.GetFlatness()*mult);
00317         if(a.HasMagnitudeKurtosis())
00318                 tmpD.SetMagnitudeKurtosis(a.GetMagnitudeKurtosis()*mult);
00319         if(a.HasMaxMagFreq())
00320                 tmpD.SetMaxMagFreq(a.GetMaxMagFreq()*mult);
00321         if(a.HasLowFreqEnergyRelation())
00322                 tmpD.SetLowFreqEnergyRelation(a.GetLowFreqEnergyRelation()*mult);
00323         if(a.HasSpread())
00324                 tmpD.SetSpread(a.GetSpread()*mult);
00325         if(a.HasMagnitudeSkewness())
00326                 tmpD.SetMagnitudeSkewness(a.GetMagnitudeSkewness()*mult);
00327         if(a.HasRolloff())
00328                 tmpD.SetRolloff(a.GetRolloff()*mult);
00329         if(a.HasSlope())
00330                 tmpD.SetSlope(a.GetSlope()*mult);
00331         if(a.HasHighFrequencyContent())
00332                 tmpD.SetHighFrequencyContent(a.GetHighFrequencyContent()*mult);
00333         if(a.HasBandDescriptors())
00334                 //todo!!! We are not multiplying because we would need the operator implemented in the array
00335                 tmpD.SetBandDescriptors(a.GetBandDescriptors());
00336         if(a.HasMFCC())
00337                 //todo!!! We are not multiplying because we would need the operator implemented in the array
00338                 tmpD.SetMFCC(a.GetMFCC());
00339         if(a.HasPCP())
00340                 tmpD.SetPCP(Multiply(mult,a.GetPCP()));
00341 
00342         return tmpD;
00343 }
00344 
00345 SpectralDescriptors operator * (const SpectralDescriptors& a,const SpectralDescriptors& b)
00346 {
00347         SpectralDescriptors  tmpD;
00348         if(a.HasMean() && b.HasMean() )
00349         {
00350                 tmpD.AddMean();
00351                 tmpD.UpdateData();
00352                 tmpD.SetMean(a.GetMean()*b.GetMean());
00353         }
00354         if(a.HasGeometricMean() && b.HasGeometricMean() )
00355         {
00356                 tmpD.AddGeometricMean();
00357                 tmpD.UpdateData();
00358                 tmpD.SetGeometricMean(a.GetGeometricMean()*b.GetGeometricMean());
00359         }
00360         if(a.HasEnergy() && b.HasEnergy() )
00361         {
00362                 tmpD.AddEnergy();
00363                 tmpD.UpdateData();
00364                 tmpD.SetEnergy(a.GetEnergy()*b.GetEnergy());
00365         }
00366         if(a.HasCentroid() && b.HasCentroid() )
00367         {
00368                 tmpD.AddCentroid();
00369                 tmpD.UpdateData();
00370                 tmpD.SetCentroid(a.GetCentroid()*b.GetCentroid());
00371         }
00372         if(a.HasMoment2() && b.HasMoment2() )
00373         {
00374                 tmpD.AddMoment2();
00375                 tmpD.UpdateData();
00376                 tmpD.SetMoment2(a.GetMoment2()*b.GetMoment2());
00377         }
00378         if(a.HasMoment3() && b.HasMoment3() )
00379         {
00380                 tmpD.AddMoment3();
00381                 tmpD.UpdateData();
00382                 tmpD.SetMoment3(a.GetMoment3()*b.GetMoment3());
00383         }
00384         if(a.HasMoment4() && b.HasMoment4() )
00385         {
00386                 tmpD.AddMoment4();
00387                 tmpD.UpdateData();
00388                 tmpD.SetMoment4(a.GetMoment4()*b.HasMoment4());
00389         }
00390         if(a.HasMoment5() && b.HasMoment5())
00391         {
00392                 tmpD.AddMoment5();
00393                 tmpD.UpdateData();
00394                 tmpD.SetMoment5(a.GetMoment5()*b.GetMoment5());
00395         }
00396         if(a.HasMoment6() && b.HasMoment6() )
00397         {
00398                 tmpD.AddMoment6();
00399                 tmpD.UpdateData();
00400                 tmpD.SetMoment6(a.GetMoment6()*b.GetMoment6());
00401         }
00402         if(a.HasFlatness() && b.HasFlatness() )
00403         {
00404                 tmpD.AddFlatness();
00405                 tmpD.UpdateData();
00406                 tmpD.SetFlatness(a.GetFlatness()*b.GetFlatness());
00407         }
00408         if(a.HasMagnitudeKurtosis() && b.HasMagnitudeKurtosis() )
00409         {
00410                 tmpD.AddMagnitudeKurtosis();
00411                 tmpD.UpdateData();
00412                 tmpD.SetMagnitudeKurtosis(a.GetMagnitudeKurtosis()*b.GetMagnitudeKurtosis());
00413         }
00414         if(a.HasMaxMagFreq() && b.HasMaxMagFreq() )
00415         {
00416                 tmpD.AddMaxMagFreq();
00417                 tmpD.UpdateData();
00418                 tmpD.SetMaxMagFreq(a.GetMaxMagFreq()*b.GetMaxMagFreq());
00419         }
00420         if(a.HasLowFreqEnergyRelation() && b.HasLowFreqEnergyRelation() )
00421         {
00422                 tmpD.AddLowFreqEnergyRelation();
00423                 tmpD.UpdateData();
00424                 tmpD.SetLowFreqEnergyRelation(a.GetLowFreqEnergyRelation()*b.GetLowFreqEnergyRelation());
00425         }
00426         if(a.HasSpread() && b.HasSpread() )
00427         {
00428                 tmpD.AddSpread();
00429                 tmpD.UpdateData();
00430                 tmpD.SetSpread(a.GetSpread()*b.GetSpread());
00431         }
00432         if(a.HasMagnitudeSkewness() && b.HasMagnitudeSkewness() )
00433         {
00434                 tmpD.AddMagnitudeSkewness();
00435                 tmpD.UpdateData();
00436                 tmpD.SetMagnitudeSkewness(a.GetMagnitudeSkewness()*b.GetMagnitudeSkewness());
00437         }
00438         if(a.HasRolloff() && b.HasRolloff() )
00439         {
00440                 tmpD.AddRolloff();
00441                 tmpD.UpdateData();
00442                 tmpD.SetRolloff(a.GetRolloff()*b.GetRolloff());
00443         }
00444         if(a.HasSlope() && b.HasSlope() )
00445         {
00446                 tmpD.AddSlope();
00447                 tmpD.UpdateData();
00448                 tmpD.SetSlope(a.GetSlope()*b.GetSlope());
00449         }
00450         if(a.HasHighFrequencyContent() && b.HasHighFrequencyContent() )
00451         {
00452                 tmpD.AddHighFrequencyContent();
00453                 tmpD.UpdateData();
00454                 tmpD.SetHighFrequencyContent(a.GetHighFrequencyContent()*b.GetHighFrequencyContent());
00455         }
00456         if(a.HasBandDescriptors() && b.HasBandDescriptors() )
00457         {
00458                 tmpD.AddBandDescriptors();
00459                 tmpD.UpdateData();
00460                 //todo!!! We are not multiplying because we would need the operator implemented in the array
00461                 tmpD.SetBandDescriptors(a.GetBandDescriptors()  );
00462         }
00463         if(a.HasMFCC() && b.HasMFCC() )
00464         {
00465                 tmpD.AddMFCC();
00466                 tmpD.UpdateData();
00467                 //todo!!! We are not multiplying because we would need the operator implemented in the array
00468                 tmpD.SetMFCC(a.GetMFCC() );
00469         }
00470         if(a.HasPCP() && b.HasPCP() )
00471         {
00472                 tmpD.AddPCP();
00473                 tmpD.UpdateData();
00474                 tmpD.SetPCP(Multiply(a.GetPCP(),b.GetPCP()));
00475         }       
00476         return tmpD;
00477 }
00478 
00479 
00480 SpectralDescriptors operator / (const SpectralDescriptors& a,TData div) 
00481 {
00482         return a*(1/div);
00483 }
00484 
00485 SpectralDescriptors operator + (const SpectralDescriptors& a, const SpectralDescriptors& b)
00486 {
00487         SpectralDescriptors  tmpD;
00488         if(a.HasMean() && b.HasMean() )
00489         {
00490                 tmpD.AddMean();
00491                 tmpD.UpdateData();
00492                 tmpD.SetMean(a.GetMean()+b.GetMean());
00493         }
00494         if(a.HasGeometricMean() && b.HasGeometricMean() )
00495         {
00496                 tmpD.AddGeometricMean();
00497                 tmpD.UpdateData();
00498                 tmpD.SetGeometricMean(a.GetGeometricMean()+b.GetGeometricMean());
00499         }
00500         if(a.HasEnergy() && b.HasEnergy() )
00501         {
00502                 tmpD.AddEnergy();
00503                 tmpD.UpdateData();
00504                 tmpD.SetEnergy(a.GetEnergy()+b.GetEnergy());
00505         }
00506         if(a.HasCentroid() && b.HasCentroid() )
00507         {
00508                 tmpD.AddCentroid();
00509                 tmpD.UpdateData();
00510                 tmpD.SetCentroid(a.GetCentroid()+b.GetCentroid());
00511         }
00512         if(a.HasMoment2() && b.HasMoment2() )
00513         {
00514                 tmpD.AddMoment2();
00515                 tmpD.UpdateData();
00516                 tmpD.SetMoment2(a.GetMoment2()+b.GetMoment2());
00517         }
00518         if(a.HasMoment3() && b.HasMoment3() )
00519         {
00520                 tmpD.AddMoment3();
00521                 tmpD.UpdateData();
00522                 tmpD.SetMoment3(a.GetMoment3()+b.GetMoment3());
00523         }
00524         if(a.HasMoment4() && b.HasMoment4() )
00525         {
00526                 tmpD.AddMoment4();
00527                 tmpD.UpdateData();
00528                 tmpD.SetMoment4(a.GetMoment4()+b.HasMoment4());
00529         }
00530         if(a.HasMoment5() && b.HasMoment5())
00531         {
00532                 tmpD.AddMoment5();
00533                 tmpD.UpdateData();
00534                 tmpD.SetMoment5(a.GetMoment5()+b.GetMoment5());
00535         }
00536         if(a.HasMoment6() && b.HasMoment6() )
00537         {
00538                 tmpD.AddMoment6();
00539                 tmpD.UpdateData();
00540                 tmpD.SetMoment6(a.GetMoment6()+b.GetMoment6());
00541         }
00542         if(a.HasFlatness() && b.HasFlatness() )
00543         {
00544                 tmpD.AddFlatness();
00545                 tmpD.UpdateData();
00546                 tmpD.SetFlatness(a.GetFlatness()+b.GetFlatness());
00547         }
00548         if(a.HasMagnitudeKurtosis() && b.HasMagnitudeKurtosis() )
00549         {
00550                 tmpD.AddMagnitudeKurtosis();
00551                 tmpD.UpdateData();
00552                 tmpD.SetMagnitudeKurtosis(a.GetMagnitudeKurtosis()+b.GetMagnitudeKurtosis());
00553         }
00554         if(a.HasMaxMagFreq() && b.HasMaxMagFreq() )
00555         {
00556                 tmpD.AddMaxMagFreq();
00557                 tmpD.UpdateData();
00558                 tmpD.SetMaxMagFreq(a.GetMaxMagFreq()+b.GetMaxMagFreq());
00559         }
00560         if(a.HasLowFreqEnergyRelation() && b.HasLowFreqEnergyRelation() )
00561         {
00562                 tmpD.AddLowFreqEnergyRelation();
00563                 tmpD.UpdateData();
00564                 tmpD.SetLowFreqEnergyRelation(a.GetLowFreqEnergyRelation()+b.GetLowFreqEnergyRelation());
00565         }
00566         if(a.HasSpread() && b.HasSpread() )
00567         {
00568                 tmpD.AddSpread();
00569                 tmpD.UpdateData();
00570                 tmpD.SetSpread(a.GetSpread()+b.GetSpread());
00571         }
00572         if(a.HasMagnitudeSkewness() && b.HasMagnitudeSkewness() )
00573         {
00574                 tmpD.AddMagnitudeSkewness();
00575                 tmpD.UpdateData();
00576                 tmpD.SetMagnitudeSkewness(a.GetMagnitudeSkewness()+b.GetMagnitudeSkewness());
00577         }
00578         if(a.HasRolloff() && b.HasRolloff() )
00579         {
00580                 tmpD.AddRolloff();
00581                 tmpD.UpdateData();
00582                 tmpD.SetRolloff(a.GetRolloff()+b.GetRolloff());
00583         }
00584         if(a.HasSlope() && b.HasSlope() )
00585         {
00586                 tmpD.AddSlope();
00587                 tmpD.UpdateData();
00588                 tmpD.SetSlope(a.GetSlope()+b.GetSlope());
00589         }
00590         if(a.HasHighFrequencyContent() && b.HasHighFrequencyContent() )
00591         {
00592                 tmpD.AddHighFrequencyContent();
00593                 tmpD.UpdateData();
00594                 tmpD.SetHighFrequencyContent(a.GetHighFrequencyContent()+b.GetHighFrequencyContent());
00595         }
00596         if(a.HasBandDescriptors() && b.HasBandDescriptors() )
00597         {
00598                 tmpD.AddBandDescriptors();
00599                 tmpD.UpdateData();
00600                 //todo!!! We are not multiplying because we would need the operator implemented in the array
00601                 tmpD.SetBandDescriptors(a.GetBandDescriptors() /* + b.GetBandDescriptors()*/ );
00602         }
00603         if(a.HasMFCC() && b.HasMFCC() )
00604         {
00605                 tmpD.AddMFCC();
00606                 tmpD.UpdateData();
00607                 //todo!!! We are not multiplying because we would need the operator implemented in the array
00608                 tmpD.SetMFCC(a.GetMFCC() /* + b.GetMFCC() */);
00609         }
00610         if(a.HasPCP() && b.HasPCP() )
00611         {
00612                 tmpD.AddPCP();
00613                 tmpD.UpdateData();
00614                 tmpD.SetPCP(Add(a.GetPCP(),b.GetPCP()));
00615         }
00616                 
00617         return tmpD;
00618 
00619 }
00620 
00621 
00622 SpectralDescriptors operator * (TData mult,const SpectralDescriptors& a)
00623 {
00624         return a*mult;
00625 }
00626 
00627 
00628 };
00629 
Generated by  doxygen 1.6.3