SpectralDescriptors.cxx
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
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
00037 if (sizea==0) {
00038 result=b;
00039 return result;
00040 }
00041 if (sizeb==0) {
00042 result=a;
00043 return result;
00044 }
00045
00046
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 {
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
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
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
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
00158
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
00212
00213 TData SpectralDescriptors::ComputeSpectralFlatness()
00214 {
00215 return mpStats->GetFlatness();
00216 }
00217
00218
00219
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
00230
00231 }
00232
00241 TData SpectralDescriptors::ComputeMaxMagFreq()
00242 {
00243
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
00257 return (TData) index * mDeltaFreq;
00258 }
00259
00260
00261
00262 TData SpectralDescriptors::ComputeLowFreqEnergyRelation()
00263 {
00264
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
00335 tmpD.SetBandDescriptors(a.GetBandDescriptors());
00336 if(a.HasMFCC())
00337
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
00461 tmpD.SetBandDescriptors(a.GetBandDescriptors() );
00462 }
00463 if(a.HasMFCC() && b.HasMFCC() )
00464 {
00465 tmpD.AddMFCC();
00466 tmpD.UpdateData();
00467
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
00601 tmpD.SetBandDescriptors(a.GetBandDescriptors() );
00602 }
00603 if(a.HasMFCC() && b.HasMFCC() )
00604 {
00605 tmpD.AddMFCC();
00606 tmpD.UpdateData();
00607
00608 tmpD.SetMFCC(a.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