SMSPitchShift.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 "SMSPitchShift.hxx"
00023 #include "ProcessingFactory.hxx"
00024 
00025 
00026 namespace CLAM
00027 {
00028 
00029 namespace Hidden
00030 {
00031         static const char * metadata[] = {
00032                 "key", "SMSPitchShift",
00033                 "category", "SMS Transformations",
00034                 "description", "SMSPitchShift",
00035                 0
00036         };
00037         static FactoryRegistrator<ProcessingFactory, SMSPitchShift> reg = metadata;
00038 }
00039 
00040 bool SMSPitchShift::Do(const SpectralPeakArray& inPeaks,
00041                 const Fundamental& inFund, 
00042                 const Spectrum& inRes, 
00043                 SpectralPeakArray& outPeaks,
00044                 Fundamental& outFund,
00045                 Spectrum& outRes)
00046 {
00047         bool ignoreResidual = mIgnoreResidual.GetLastValue()>0.;
00048         if (!mConfig.GetPreserveOuts()) //TODO big cludge for streaming
00049         {
00050                 outPeaks = inPeaks; 
00051                 outFund = inFund;
00052                 if (!ignoreResidual)
00053                         outRes = inRes;
00054         }
00055 
00056         TData amount = mPitchSteps.GetLastValue();
00057         if(amount==1)//no pitch shift
00058                 return true;
00059         
00060         TData spectralRange = inRes.GetSpectralRange();
00061         TData fundamental = inFund.GetFreq(0);
00062         bool isHarmonic = fundamental > .5;
00063         mIsHarmonic.DoControl( isHarmonic );
00064 
00065         for (int i=0;i<inFund.GetnCandidates();i++)
00066                 outFund.SetFreq(i,inFund.GetFreq(i)*amount);
00067 
00068         mSpectralEnvelope.SetSpectralRange(spectralRange);
00069         
00070         bool haveEnvelope=false;
00071 
00072         //First extract spectral envelope
00073         if(isHarmonic)
00074                 haveEnvelope = mSpectralEnvelopeExtract.Do(inPeaks,mSpectralEnvelope);
00075 
00076         if(&outPeaks!=&inPeaks)//TODO: this is already solved inPeaks new DT
00077                 outPeaks=inPeaks;
00078         DataArray& iFreqArray=inPeaks.GetFreqBuffer();
00079         DataArray& oFreqArray=outPeaks.GetFreqBuffer();
00080         DataArray& iBinPosArray=inPeaks.GetBinPosBuffer();
00081         DataArray& oBinPosArray=outPeaks.GetBinPosBuffer();
00082         TSize nPeaks=inPeaks.GetnPeaks();
00083         
00084         //Shift all peaks
00085         for(int i=0;i<nPeaks;i++)
00086         {
00087                 TData newFreq=iFreqArray[i]*amount;
00088                 if (newFreq>=spectralRange)
00089                 {
00090                         outPeaks.SetnPeaks(i);
00091                         break;
00092                 }
00093                 oFreqArray[i]=newFreq;
00094                 oBinPosArray[i]=iBinPosArray[i]*amount;
00095         }
00096 
00097         //Apply original spectral shape and comb filter the residual
00098         if (isHarmonic)
00099         {
00100                 if (haveEnvelope)
00101                         mSpectralEnvelopeApply.Do(outPeaks,mSpectralEnvelope,outPeaks);
00102                 if (false && !ignoreResidual)
00103                 {
00104                         mFDCombFilter.mFreq.DoControl(fundamental*amount);
00105                         mFDCombFilter.Do(inRes,outRes);
00106                 }
00107         }
00108         return true;
00109 }
00110 
00111 bool SMSPitchShift::Do(const Frame& in, Frame& out)
00112 {
00113         return Do( in.GetSpectralPeakArray(),
00114                         in.GetFundamental(), 
00115                         in.GetResidualSpec(), 
00116                         out.GetSpectralPeakArray(),
00117                         out.GetFundamental(), 
00118                         out.GetResidualSpec());
00119 }
00120 
00121 
00122 }
00123 
Generated by  doxygen 1.6.3