SpectralPeakArrayInterpolator.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 "SpecTypeFlags.hxx"
00024 #include "SpectralPeakArrayInterpolator.hxx"
00025 #include "BPF.hxx"
00026 #include "Point.hxx"
00027 #include "Spectrum.hxx"
00028 
00029 namespace CLAM {
00030 
00031         void PeaksInterpConfig::DefaultInit()
00032         {
00033                 //test
00034                 AddAll();
00035                 UpdateData();
00036                 DefaultValues();
00037         }
00038 
00039         void PeaksInterpConfig::DefaultValues()
00040         {
00041                 SetUseSpectralShape(false);
00042         }
00043 
00044 
00045         SpectralPeakArrayInterpolator::SpectralPeakArrayInterpolator()
00046                 :       mMagInterpolationFactorCtl("MagInterpolationFactor",this),
00047                         mFreqInterpolationFactorCtl("FreqInterpolationFactor",this),
00048                         mPitchInterpolationFactorCtl("PitchInterpolationFactor",this),
00049                         mPitch1Ctl("Pitch1",this),
00050                         mPitch2Ctl("Pitch2",this),
00051                         mIsHarmonicCtl("IsHarmonic",this),
00052                         mIn1("Input 1",this),
00053                         mIn2("Input 2",this),
00054                         mOut("Output",this),
00055                         mpSpectralShape(0)
00056         {
00057                 Configure(PeaksInterpConfig());
00058         }
00059 
00060         SpectralPeakArrayInterpolator::SpectralPeakArrayInterpolator(const PeaksInterpConfig &c)
00061                 :       mMagInterpolationFactorCtl("MagInterpolationFactor",this),
00062                         mFreqInterpolationFactorCtl("FreqInterpolationFactor",this),
00063                         mPitchInterpolationFactorCtl("PitchInterpolationFactor",this),
00064                         mPitch1Ctl("Pitch1",this),
00065                         mPitch2Ctl("Pitch2",this),
00066                         mIsHarmonicCtl("IsHarmonic",this),
00067                         mIn1("Input 1",this),
00068                         mIn2("Input 2",this),
00069                         mOut("Output",this),
00070                         mpSpectralShape(0)
00071         {
00072                 Configure(c);
00073         }
00074 
00075 
00076         bool SpectralPeakArrayInterpolator::ConcreteConfigure(const ProcessingConfig&c)
00077         {
00078                 CopyAsConcreteConfig(mConfig, c);
00079                 //Initialize interpolation factor control from value in the configuration
00080                 mMagInterpolationFactorCtl.DoControl(mConfig.GetMagInterpolationFactor());
00081                 mFreqInterpolationFactorCtl.DoControl(mConfig.GetFreqInterpolationFactor());
00082                 mPitchInterpolationFactorCtl.DoControl(mConfig.GetPitchInterpolationFactor());
00083                 mIsHarmonicCtl.DoControl(mConfig.GetHarmonic());
00084 
00085                 return true;
00086         }
00087 
00088         // Unsupervised Do() function.
00089         bool SpectralPeakArrayInterpolator::Do(const SpectralPeakArray& in1, const SpectralPeakArray& in2, SpectralPeakArray& out)
00090         {
00091                 CLAM_DEBUG_ASSERT(IsRunning(),
00092                         "SpectralPeakArrayInterpolator::Do(): Not in execution mode");
00093 
00094                 //First, we get values of the internal controls
00095                 TData magFactor=mMagInterpolationFactorCtl.GetLastValue();
00096                 TData freqFactor=mFreqInterpolationFactorCtl.GetLastValue();
00097 
00098                 TData pitch1=mPitch1Ctl.GetLastValue();
00099                 TData pitch2=mPitch2Ctl.GetLastValue();
00100                 TData pitchFactor=mPitchInterpolationFactorCtl.GetLastValue();
00101 
00102                 //we then chek if interpolation really needs to be done
00103                 if(magFactor>0.99&&freqFactor>0.99&&pitchFactor>0.99)
00104                 {
00105                         //we return target spectral peak array
00106                         out=in2;
00107                         return true;
00108                 }
00109                 if(magFactor<0.01&&freqFactor<0.01&&pitchFactor<0.01)
00110                 {
00111                         //we return source spectral peak array
00112                         out=in1;
00113                         return true;
00114                 }
00115                 
00116 
00117                 //else, it means we are in a intermediate point and we need to interpolate
00118 
00119                 //we need to copy input peak arrays to convert them to linear
00120                 SpectralPeakArray tmpIn1=in1;
00121                 SpectralPeakArray tmpIn2=in2;
00122                 tmpIn1.ToLinear();
00123                 tmpIn2.ToLinear();
00124 
00125                 int nPeaks1=in1.GetnPeaks();
00126                 int nPeaks2=in2.GetnPeaks();
00127 
00128                 if(nPeaks1==0||nPeaks2==0)
00129                 {
00130                         out=in1;
00131                         return true;
00132                 }
00133 
00134                 //We initialize out with tmpIn1
00135                 out=tmpIn1;
00136                 
00137                 DataArray& in1Mag=tmpIn1.GetMagBuffer();
00138                 DataArray& in2Mag=tmpIn2.GetMagBuffer();
00139                 DataArray& outMag=out.GetMagBuffer();
00140 
00141                 DataArray& in1Freq=tmpIn1.GetFreqBuffer();
00142                 DataArray& in2Freq=tmpIn2.GetFreqBuffer();
00143                 DataArray& outFreq=out.GetFreqBuffer();
00144 
00145                 IndexArray& in1Index=tmpIn1.GetIndexArray();
00146                 IndexArray& in2Index=tmpIn2.GetIndexArray();
00147                 IndexArray& outIndex=out.GetIndexArray();
00148                 
00149                 
00150                 //Unused var: TData factor2=(TData)nPeaks2/nPeaks1;
00151                 
00152 
00153                 //TODO: this computation is duplicated
00154                 TData newPitch=pitch1*(1-pitchFactor)+pitch2*pitchFactor;
00155 
00156                 int pos=0,i=0;
00157                 TData lastFreq=0;
00158                 do
00159                 {
00160                         if(!mIsHarmonicCtl.GetLastValue())
00161                         {
00162                                 TIndex id=in1.GetIndex(i);
00163                                 int posIn2=in2.GetPositionFromIndex(id);
00164                                 if(posIn2>0)//found matching peak
00165                                 {
00166                                         outMag[i]=in1Mag[i]*(1-magFactor)+in2Mag[posIn2]*magFactor;
00167                                         outFreq[i]=in1Freq[i]*(1-freqFactor)+in2Freq[posIn2]*freqFactor;
00168                                         outIndex[i]=id;
00169                                         lastFreq=outFreq[i];
00170                                 }
00171                                 else
00172                                 {
00173                                         outMag[i]=in1Mag[i]*(1-magFactor);
00174                                         outFreq[i]=in1Freq[i];
00175                                         outIndex[i]=id;
00176                                         lastFreq=outFreq[i];
00177 
00178                                 }
00179                                         
00180                                 /*outMag[i]=in1Mag[i]*(1-magFactor)+in2Mag[i*factor2]*magFactor;
00181                                 outFreq[i]=in1Freq[i]*(1-freqFactor)+in2Freq[i*factor2]*freqFactor;
00182                                 CLAM_DEBUG_ASSERT(outFreq[i]>=lastFreq,"Error");
00183                                 lastFreq=outFreq[i];
00184                                 CLAM_DEBUG_ASSERT(outMag[i]<1,"Error");
00185                                 CLAM_DEBUG_ASSERT(outMag[i]>-1,"Error");
00186                                 CLAM_DEBUG_ASSERT(outFreq[i]<22000,"Error");
00187                                 CLAM_DEBUG_ASSERT(outFreq[i]>=0,"Error");*/
00188                         }
00189                         else if(FindHarmonic(in2Index,in1Index[i],pos))
00190                         {
00191                                 //Morphing Using Harmonic No*/
00192                                 outMag[i]=in1Mag[i]*(1-magFactor)+in2Mag[pos]*magFactor;
00193                                 outFreq[i]=((in1Freq[i]/pitch1)*(1-freqFactor)+(in2Freq[pos]/pitch2)*freqFactor)*newPitch;
00194                                 CLAM_DEBUG_ASSERT(outFreq[i]>lastFreq,"Error");
00195                                 lastFreq=outFreq[i];
00196                                 CLAM_DEBUG_ASSERT(outMag[i]<1,"Error");
00197                                 CLAM_DEBUG_ASSERT(outMag[i]>-1,"Error");
00198                                 CLAM_DEBUG_ASSERT(outFreq[i]<22000,"Error");
00199                                 CLAM_DEBUG_ASSERT(outFreq[i]>=0,"Error");
00200                         }
00201                         else
00202                         {
00203                                 if(i>in2.GetnPeaks()-1)
00204                                 {
00205                                         out.SetnPeaks(i-1);
00206                                         break;
00207                                 }
00208                                 outMag[i]=TData(0.0000000001);
00209                                 outFreq[i]=lastFreq+=100;
00210                         }
00211                         i++;
00212                 }while(i<nPeaks1);
00213                 
00214                 //Finally we convert output to dB
00215                 out.TodB();
00216 
00217                 return true;
00218         }
00219 
00220         // Unsupervised Do() function.
00221         bool SpectralPeakArrayInterpolator::Do(const SpectralPeakArray& in1, const SpectralPeakArray& in2,const Spectrum& spectralShape, SpectralPeakArray& out)
00222         {
00223                 CLAM_DEBUG_ASSERT(IsRunning(),
00224                         "SpectralPeakArrayInterpolator::Do(): Not in execution mode");
00225 
00226                 //First, we get values of the internal controls
00227                 TData freqFactor=mFreqInterpolationFactorCtl.GetLastValue();
00228 
00229                 TData pitch1=mPitch1Ctl.GetLastValue();
00230                 TData pitch2=mPitch2Ctl.GetLastValue();
00231                 TData pitchFactor=mPitchInterpolationFactorCtl.GetLastValue();
00232 
00233                 //else, it means we are in a intermediate point and we need to interpolate
00234 
00235                 //we need to copy input peak arrays to convert them to linear
00236                 SpectralPeakArray tmpIn1=in1;
00237                 SpectralPeakArray tmpIn2=in2;
00238                 tmpIn1.ToLinear();
00239                 tmpIn2.ToLinear();
00240 
00241                 int nPeaks1=in1.GetnPeaks();
00242                 int nPeaks2=in2.GetnPeaks();
00243 
00244                 if(nPeaks1==0||nPeaks2==0)
00245                 {
00246                         out=in1;
00247                         return true;
00248                 }
00249 
00250                 //We initialize out with tmpIn1
00251                 out=tmpIn1;
00252                 
00253                 DataArray& in1Mag=tmpIn1.GetMagBuffer();
00254                 DataArray& in2Mag=tmpIn2.GetMagBuffer();
00255                 DataArray& outMag=out.GetMagBuffer();
00256 
00257                 DataArray& in1Freq=tmpIn1.GetFreqBuffer();
00258                 DataArray& in2Freq=tmpIn2.GetFreqBuffer();
00259                 DataArray& outFreq=out.GetFreqBuffer();
00260 
00261                 IndexArray& in1Index=tmpIn1.GetIndexArray();
00262                 IndexArray& in2Index=tmpIn2.GetIndexArray();
00263                 
00264                 
00265                 
00266                 TData factor2=(TData)nPeaks2/nPeaks1;
00267                 
00268 
00269                 //TODO: this computation is duplicated
00270                 TData newPitch=pitch1*(1-pitchFactor)+pitch2*pitchFactor;
00271 
00272                 int pos=0,i=0;
00273                 TData lastFreq=0;
00274                 TData magFactor;
00275                 do
00276                 {
00277                         
00278                         if(!mIsHarmonicCtl.GetLastValue())
00279                         {
00280                                 outFreq[i]=in1Freq[i]*(1-freqFactor)+in2Freq[ int(i*factor2) ]*freqFactor;
00281                                 CLAM_DEBUG_ASSERT(outFreq[i]>=lastFreq,"Error");
00282                                 lastFreq=outFreq[i];
00283 
00284                                 magFactor=spectralShape.GetMag(outFreq[i]);
00285                                 if(magFactor>1) magFactor=1;
00286                                 if(magFactor<0) magFactor=0;
00287                                 outMag[i]=in1Mag[i]*(1-magFactor)+in2Mag[ int(i*factor2) ]*magFactor;
00288                                 CLAM_DEBUG_ASSERT(outMag[i]<1,"Error");
00289                                 CLAM_DEBUG_ASSERT(outMag[i]>-1,"Error");
00290                                 CLAM_DEBUG_ASSERT(outFreq[i]<22000,"Error");
00291                                 CLAM_DEBUG_ASSERT(outFreq[i]>=0,"Error");
00292                         }
00293                         else if(FindHarmonic(in2Index,in1Index[i],pos))
00294                         {
00295                                 //Morphing Using Harmonic No*/
00296                                 
00297                                 outFreq[i]=((in1Freq[i]/pitch1)*(1-freqFactor)+(in2Freq[pos]/pitch2)*freqFactor)*newPitch;
00298                                 CLAM_DEBUG_ASSERT(outFreq[i]>lastFreq,"Error");
00299                                 lastFreq=outFreq[i];
00300                                 
00301                                 magFactor=spectralShape.GetMag(outFreq[i]);
00302                                 if(magFactor>1) magFactor=1;
00303                                 if(magFactor<0) magFactor=0;
00304                                 outMag[i]=in1Mag[i]*(1-magFactor)+in2Mag[pos]*magFactor;
00305                                 CLAM_DEBUG_ASSERT(outMag[i]<1,"Error");
00306                                 CLAM_DEBUG_ASSERT(outMag[i]>-1,"Error");
00307                                 CLAM_DEBUG_ASSERT(outFreq[i]<22000,"Error");
00308                                 CLAM_DEBUG_ASSERT(outFreq[i]>=0,"Error");
00309                         }
00310                         else
00311                         {
00312                                 if(i>in2.GetnPeaks()-1)
00313                                 {
00314                                         out.SetnPeaks(i-1);
00315                                         break;
00316                                 }
00317                                 outMag[i]=TData(0.0000000001);
00318                                 outFreq[i]=lastFreq+=100;
00319                         }
00320                         i++;
00321                 }while(i<nPeaks1);
00322                 
00323                 //Finally we convert output to dB
00324                 out.TodB();
00325 
00326                 return true;
00327         }
00328 
00329         bool SpectralPeakArrayInterpolator::Do(void)
00330         {
00331                 if(mConfig.GetUseSpectralShape())
00332                         return Do( mIn1.GetData(), mIn2.GetData(), *mpSpectralShape, mOut.GetData() );
00333                 else
00334                         return Do(mIn1.GetData(),mIn2.GetData(),mOut.GetData());
00335         }
00336 
00337         
00339         bool SpectralPeakArrayInterpolator::FindHarmonic(const IndexArray& indexArray,int index,int& lastPosition)
00340         {
00341                 int i;
00342                 bool found=false;
00343                 int nPeaks=indexArray.Size();
00344                 for(i=lastPosition;i<nPeaks;i++)
00345                 {
00346                         if(indexArray[i]==index)
00347                         {
00348                                 lastPosition=i;
00349                                 found=true;
00350                                 break;
00351                         }
00352                 }
00353                 return found;
00354 
00355         }
00356 }
00357 

Generated on Tue Aug 12 22:33:45 2008 for CLAM by  doxygen 1.5.5