SpectralEnvelopeExtract.cxx

Go to the documentation of this file.
00001 /*
00002  * Copyright (c) 2001-2006 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 "SpectralEnvelopeExtract.hxx"
00024 #include "Spectrum.hxx"
00025 #include "SpecTypeFlags.hxx"
00026 #include "SpectralPeakArray.hxx"
00027 
00028 #define CLASS "SpectralEnvelopeExtract"
00029 
00030 namespace CLAM {
00031 
00032         /* The  Configuration object has at least to have a name */
00033 
00034         void SpectralEnvelopeExtractConfig::DefaultInit()
00035         {
00036                 AddAll();
00037                 UpdateData();
00038                 DefaultValues();
00039         }
00040 
00041         
00042         void SpectralEnvelopeExtractConfig::DefaultValues()
00043         {
00044                 SetInterpolationType(EInterpolation::eSpline);
00045                 SetMaxPeaks(200);
00046         }
00047 
00048 
00049         /* Processing  object Method  implementations */
00050 
00051         SpectralEnvelopeExtract::SpectralEnvelopeExtract()
00052         {
00053                 Configure(SpectralEnvelopeExtractConfig());
00054         }
00055 
00056         SpectralEnvelopeExtract::SpectralEnvelopeExtract(const SpectralEnvelopeExtractConfig &c = SpectralEnvelopeExtractConfig())
00057         {
00058                 Configure(c);
00059         }
00060 
00061         SpectralEnvelopeExtract::~SpectralEnvelopeExtract()
00062         {}
00063 
00064 
00065         /* Configure the Processing Object according to the Config object */
00066 
00067         bool SpectralEnvelopeExtract::ConcreteConfigure(const ProcessingConfig& c)
00068         {
00069 
00070                 CopyAsConcreteConfig(mConfig, c);
00071                 mMagBPF.SetIntpType(mConfig.GetInterpolationType());
00072                 mPhaseBPF.SetIntpType(EInterpolation::eLinear);
00073                 return true;
00074         }
00075 
00076         /* Setting Prototypes for faster processing */
00077 
00078         bool SpectralEnvelopeExtract::SetPrototypes(const SpectralPeakArray& input,Spectrum& output)
00079         {
00080                 return true;
00081         }
00082 
00083         bool SpectralEnvelopeExtract::SetPrototypes()
00084         {
00085                 return true;
00086         }
00087         
00088         bool SpectralEnvelopeExtract::UnsetPrototypes()
00089         {
00090                 return true;
00091         }
00092 
00093         /* The supervised Do() function */
00094 
00095         bool  SpectralEnvelopeExtract::Do(void) 
00096         {
00097                 CLAM_ASSERT(false,CLASS"::Do(): Supervised mode not implemented");
00098                 return false;
00099         }
00100 
00101         /* The  unsupervised Do() function */
00102 
00103         bool  SpectralEnvelopeExtract::Do(const SpectralPeakArray& input, Spectrum& output)
00104         {
00105                 output.SetScale(input.GetScale());
00106                 
00107                 TSize nPeaks=input.GetnPeaks();
00108                                 
00109                 if (nPeaks<4) return false; //cannot extract an envelope out of only 3 peaks!
00110 
00111                 CheckOutputType(output);
00112 
00113                 DataArray& magBuffer=input.GetMagBuffer();
00114                 DataArray& phaseBuffer=input.GetPhaseBuffer();
00115                 DataArray& freqBuffer=input.GetFreqBuffer();
00116 
00117                 Array<Point>& magPointArray=output.GetMagBPF().GetPointArray();
00118                 Array<Point>& phasePointArray=output.GetPhaseBPF().GetPointArray();
00119         
00120                 //Max number of points allowed: should be a config param
00121                 magPointArray.Resize(mConfig.GetMaxPeaks());
00122                 magPointArray.SetSize(mConfig.GetMaxPeaks());
00123                 phasePointArray.Resize(mConfig.GetMaxPeaks());
00124                 phasePointArray.SetSize(mConfig.GetMaxPeaks());
00125                 
00126                 
00127                 for(int i=0;i<nPeaks;i++)
00128                 {
00129                         magPointArray[i+1].SetX(freqBuffer[i]);
00130                         magPointArray[i+1].SetY(magBuffer[i]);
00131 
00132                         phasePointArray[i+1].SetX(freqBuffer[i]);
00133                         phasePointArray[i+1].SetY(phaseBuffer[i]);
00134 
00135                 }
00136                 
00137                 //todo: a lot of duplicated code, should extract in different functions
00138                 if(input.GetScale()==EScale::eLog)
00139                 {
00140                 
00141                         //we now set first point (maybe we should do the same as with last point?)
00142                         magPointArray[0].SetX(0);
00143                         magPointArray[0].SetY(magBuffer[0]-3);
00144                         phasePointArray[0].SetX(0);
00145                         phasePointArray[0].SetY(0);
00146                         nPeaks++;
00147                         
00148                         /* we keep adding points to bpf until magnitude is insignificant 
00149                         (note that we add points outside the spectral range) */
00150                         TData lastFreq=freqBuffer[nPeaks-2];
00151                         TData freqGap=lastFreq-freqBuffer[nPeaks-3];
00152                         TData currentFreq=lastFreq+freqGap;
00153                         TData currentMag=magBuffer[nPeaks-2];
00154                 
00155                         while(currentMag>-200)
00156                         {
00157                                 currentMag-=(currentFreq/lastFreq-1)*12;
00158                                 
00159                                 magPointArray[nPeaks].SetY(currentMag);
00160                                 magPointArray[nPeaks].SetX(currentFreq);
00161                                 phasePointArray[nPeaks].SetY(0);
00162                                 phasePointArray[nPeaks].SetX(currentFreq);
00163                                 
00164                                 currentFreq+=freqGap;
00165                                 nPeaks++;
00166                                 if(nPeaks==mConfig.GetMaxPeaks()) break;
00167                                 
00168                         }
00169                         //we resize arrays to final size
00170                         magPointArray.Resize(nPeaks);
00171                         magPointArray.SetSize(nPeaks);
00172                         phasePointArray.Resize(nPeaks);
00173                         phasePointArray.SetSize(nPeaks);
00174                         
00175 
00176                 }
00177                 else
00178                 {
00179                         //we now set first point (maybe we should do the same as with last point?)
00180                         magPointArray[0].SetX(0);
00181                         magPointArray[0].SetY(magBuffer[0]*0.5);
00182                         phasePointArray[0].SetX(0);
00183                         phasePointArray[0].SetY(0);
00184                         nPeaks++;
00185                         
00186                         /* we keep adding points to bpf until magnitude is insignificant 
00187                         (note that we add points outside the spectral range) */
00188                         TData lastFreq=freqBuffer[nPeaks-2];
00189                         TData freqGap=lastFreq-freqBuffer[nPeaks-3];
00190                         TData currentFreq=lastFreq+freqGap;
00191                         TData currentMag=magBuffer[nPeaks-2];
00192                 
00193                 
00194                         while(currentMag<0.0000000001)
00195                         {
00196                                 currentMag*=CLAM_pow(0.06,(double)(currentFreq/lastFreq-1.0));
00197                                 
00198                                 magPointArray[nPeaks].SetY(currentMag);
00199                                 magPointArray[nPeaks].SetX(currentFreq);
00200                                 phasePointArray[nPeaks].SetY(0);
00201                                 phasePointArray[nPeaks].SetX(currentFreq);
00202                                 
00203                                 currentFreq+=freqGap;
00204                                 nPeaks++;
00205                                 if(nPeaks==mConfig.GetMaxPeaks()) break;
00206                         }
00207                         
00208                         //we resize arrays to final size
00209                         magPointArray.Resize(nPeaks);
00210                         magPointArray.SetSize(nPeaks);
00211                         phasePointArray.Resize(nPeaks);
00212                         phasePointArray.SetSize(nPeaks);
00213                         
00214                 }
00215                 
00216                 output.SetSize(nPeaks);
00217                 output.GetMagBPF().UpdateSplineTable();
00218                 
00219                 return true;
00220         }
00221 
00222         bool SpectralEnvelopeExtract::CheckOutputType(Spectrum& out) 
00223         {
00224                 SpecTypeFlags tmpFlags;
00225                 
00226                 tmpFlags.bMagPhaseBPF=1;
00227                 tmpFlags.bMagPhase=0;
00228                 out.SetType(tmpFlags);
00229 
00230                 
00231                 out.SetMagBPF(mMagBPF);
00232                 out.SetPhaseBPF(mPhaseBPF);
00233                 
00234                 
00235                 return true;
00236         }
00237 };//namespace CLAM
00238 
Generated by  doxygen 1.6.3