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