SpectralSynthesis.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 "SpectralSynthesis.hxx"
00023 #include "ProcessingFactory.hxx"
00024 
00025 #include <iostream>
00026 
00027 namespace CLAM
00028 {
00029 
00030 namespace Hidden 
00031 {
00032         static const char * metadata[] = {
00033                 "key", "SpectralSynthesis",
00034                 "category", "Synthesis",
00035                 "description", "SpectralSynthesis",
00036                 0
00037         };
00038         static FactoryRegistrator<ProcessingFactory, SpectralSynthesis> reg = metadata;
00039 }
00040 
00041 void SpectralSynthesis::AttachChildren()
00042 {
00043         mPO_AnalWindowGen.SetParent(this);
00044         mPO_SynthWindowGen.SetParent(this);
00045         mPO_AudioProduct.SetParent(this);
00046         mPO_CircularShift.SetParent(this);
00047         mPO_IFFT.SetParent(this);
00048         
00049 }
00050 
00051 SpectralSynthesis::SpectralSynthesis()
00052         :  mInput("Input",this),
00053            mOutput("Output",this)
00054 {
00055         Configure(SpectralSynthesisConfig());
00056         AttachChildren();
00057 }
00058 
00059 SpectralSynthesis::SpectralSynthesis(const SpectralSynthesisConfig& cfg)
00060         : mInput("Input",this),
00061           mOutput("Output",this)
00062 {
00063         Configure(cfg);
00064         AttachChildren();
00065 }
00066 
00067 SpectralSynthesis::~SpectralSynthesis()
00068 {
00069         
00070 }
00071 
00072 bool SpectralSynthesis::ConfigureChildren()
00073 {
00074         
00075         //instantiate analysis window generator
00076         if(!mPO_AnalWindowGen.Configure(mConfig.GetAnalWindowGenerator()))
00077                 return false;
00078 
00079         //instantiate synthesis window generator
00080         if(!mPO_SynthWindowGen.Configure(mConfig.GetSynthWindowGenerator()))
00081                 return false;
00082         
00083         //Instantiate Circular Shift
00084         if(!mPO_CircularShift.Configure(mConfig.GetCircularShift()))
00085                 return false;           
00086 
00087 
00088         //instantiate IFFT
00089         IFFTConfig IFFTCFG;
00090         IFFTCFG.SetAudioSize(mConfig.GetIFFT().GetAudioSize());
00091         if(!mPO_IFFT.Configure(IFFTCFG))
00092                 return false;           
00093                 
00094         return true;
00095 }
00096 
00097 void SpectralSynthesis::ConfigureData()
00098 {
00100         //INSTANIATE PROCESSING DATA
00102 
00103         //intantiate audio used as temporary data
00104         mAudio0.SetSize(mConfig.GetIFFT().GetAudioSize());//audio used as output of the IFFT
00105 
00106         mAudio1.SetSize(mConfig.GetAnalWindowSize()-1);//audio without zeropadding
00107         
00108         mAudio2.SetSize(mConfig.GetHopSize()*2);//audio used as input of the inverse + triangular windowing 
00109         
00110         mSynthWindow.SetSize(mConfig.GetHopSize()*2+1);
00111 
00112         //initialize window
00113         Audio tmpWindow,tmpWindow2;
00114         
00115         tmpWindow.SetSize(mConfig.GetAnalWindowSize());
00116         tmpWindow2.SetSize(mConfig.GetHopSize()*2+1);
00117 
00118         mPO_AnalWindowGen.Start();
00119         mPO_AnalWindowGen.Do(tmpWindow);
00120         mPO_AnalWindowGen.Stop();
00121 
00122 
00123         //We now take only the mSynthWindowSize central samples of the inverse window
00124         tmpWindow.GetAudioChunk((int)((TData)mConfig.GetAnalWindowSize()/2-(TData)mConfig.GetHopSize()),(int)((float)mConfig.GetAnalWindowSize()/2+(float)mConfig.GetHopSize()),mSynthWindow,false);
00125 
00126 
00127 
00128         //Now we generate triangular synthesis window
00129         tmpWindow.SetSize(mConfig.GetHopSize()*2+1);
00130 
00131         mPO_SynthWindowGen.Start();
00132         mPO_SynthWindowGen.Do(tmpWindow);
00133         mPO_SynthWindowGen.Stop();
00134 
00135         
00136         //Now we multiply both windows
00137         mPO_AudioProduct.Do(tmpWindow,mSynthWindow,mSynthWindow);
00138 
00139         //now we set it to even size leaving last sample out
00140         mSynthWindow.SetSize(mConfig.GetHopSize()*2);
00141 
00142 
00143 
00144 }
00145 
00146 
00147 bool SpectralSynthesis::ConcreteConfigure(const ProcessingConfig& c)
00148 {
00149          CopyAsConcreteConfig(mConfig, c);
00150          
00151          mConfig.Sync();
00152 
00153          mOutput.SetSize( mConfig.GetHopSize()*2 );
00154          mOutput.SetHop( mConfig.GetHopSize()*2 );
00155 
00156 
00157          //CONFIGURE CHILDREN AND DATA
00158         ConfigureChildren();
00159 
00160         ConfigureData();
00161         return true;
00162 }
00163 
00164 bool SpectralSynthesis::Do(void)
00165 {
00166         bool result = Do(mInput.GetData(),mOutput.GetAudio());
00167         mInput.Consume();
00168         mOutput.Produce();
00169         return result;
00170 }
00171 
00172 
00173 bool SpectralSynthesis::Do(Spectrum& in, Audio& out)
00174 {
00175 
00176         TSize analWindowSize = mConfig.GetAnalWindowSize()-1;//note I include the minus 1!
00177         TSize hopSize = mConfig.GetHopSize();
00178 //Now we do the inverse FFT
00179         mPO_IFFT.Do(in, mAudio0);
00180 //Undoing Synthesis circular shift
00181         mPO_CircularShift.Do(mAudio0,mAudio0);
00182 //We take the central samples to multiply with the window while also undoing the zero padding
00183         int centerSample = analWindowSize*0.5;
00184         mAudio0.GetAudioChunk(centerSample-hopSize,centerSample+hopSize-1,mAudio2,false);
00185 //Aplying inverse window
00186         mPO_AudioProduct.Do(mAudio2, mSynthWindow,out);
00187 
00188         
00189         return true;
00190 }
00191 
00192 
00193 bool SpectralSynthesis::Do(Frame& in)
00194 {
00195         if(mConfig.GetResidual())
00196                 return Do(in.GetSpectrum(),in.GetAudioFrame());
00197         else
00198                 return Do(in.GetResidualSpec(),in.GetResidualAudioFrame());
00199 }
00200 
00201 bool SpectralSynthesis::Do(Segment& in)
00202 {
00203         return Do(in.GetFrame(in.mCurrentFrameIndex++));
00204 }
00205 
00206 TInt32 SpectralSynthesis::CalculatePowerOfTwo(TInt32 size)
00207 {
00208         int tmp = size;
00209         int outputSize = 1;
00210         while (tmp) 
00211         {
00212                 outputSize=outputSize << 1;
00213                 tmp=tmp >> 1;
00214         }
00215         if(outputSize == size << 1)
00216                 outputSize = outputSize >> 1;
00217         return outputSize;
00218 }
00219 
00220 
00221 }
00222 
Generated by  doxygen 1.6.3