CLAM-Development
1.1
|
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