CLAM-Development  1.4.0
SpectralSynthesis.cxx
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2001-2004 MUSIC TECHNOLOGY GROUP (MTG)
3  * UNIVERSITAT POMPEU FABRA
4  *
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19  *
20  */
21 
22 #include "SpectralSynthesis.hxx"
23 #include "ProcessingFactory.hxx"
24 
25 #include <iostream>
26 
27 namespace CLAM
28 {
29 
30 namespace Hidden
31 {
32  static const char * metadata[] = {
33  "key", "SpectralSynthesis",
34  "category", "Synthesis",
35  "description", "SpectralSynthesis",
36  0
37  };
38  static FactoryRegistrator<ProcessingFactory, SpectralSynthesis> reg = metadata;
39 }
40 
41 void SpectralSynthesis::AttachChildren()
42 {
43  mPO_AnalWindowGen.SetParent(this);
44  mPO_SynthWindowGen.SetParent(this);
45  mPO_AudioProduct.SetParent(this);
46  mPO_CircularShift.SetParent(this);
47  mPO_IFFT.SetParent(this);
48 
49 }
50 
52  : mInput("Input",this),
53  mOutput("Output",this)
54 {
56  AttachChildren();
57 }
58 
60  : mInput("Input",this),
61  mOutput("Output",this)
62 {
63  Configure(cfg);
64  AttachChildren();
65 }
66 
68 {
69 
70 }
71 
72 bool SpectralSynthesis::ConfigureChildren()
73 {
74 
75  //instantiate analysis window generator
76  if(!mPO_AnalWindowGen.Configure(mConfig.GetAnalWindowGenerator()))
77  return false;
78 
79  //instantiate synthesis window generator
80  if(!mPO_SynthWindowGen.Configure(mConfig.GetSynthWindowGenerator()))
81  return false;
82 
83  //Instantiate Circular Shift
84  if(!mPO_CircularShift.Configure(mConfig.GetCircularShift()))
85  return false;
86 
87 
88  //instantiate IFFT
89  IFFTConfig IFFTCFG;
90  IFFTCFG.SetAudioSize(mConfig.GetIFFT().GetAudioSize());
91  if(!mPO_IFFT.Configure(IFFTCFG))
92  return false;
93 
94  return true;
95 }
96 
97 void SpectralSynthesis::ConfigureData()
98 {
100  //INSTANIATE PROCESSING DATA
102 
103  //intantiate audio used as temporary data
104  mAudio0.SetSize(mConfig.GetIFFT().GetAudioSize());//audio used as output of the IFFT
105 
106  mAudio1.SetSize(mConfig.GetAnalWindowSize()-1);//audio without zeropadding
107 
108  mAudio2.SetSize(mConfig.GetHopSize()*2);//audio used as input of the inverse + triangular windowing
109 
110  mSynthWindow.SetSize(mConfig.GetHopSize()*2+1);
111 
112  //initialize window
113  Audio tmpWindow,tmpWindow2;
114 
115  tmpWindow.SetSize(mConfig.GetAnalWindowSize());
116  tmpWindow2.SetSize(mConfig.GetHopSize()*2+1);
117 
118  mPO_AnalWindowGen.Start();
119  mPO_AnalWindowGen.Do(tmpWindow);
120  mPO_AnalWindowGen.Stop();
121 
122 
123  //We now take only the mSynthWindowSize central samples of the inverse window
124  tmpWindow.GetAudioChunk((int)((TData)mConfig.GetAnalWindowSize()/2-(TData)mConfig.GetHopSize()),(int)((float)mConfig.GetAnalWindowSize()/2+(float)mConfig.GetHopSize()),mSynthWindow,false);
125 
126 
127 
128  //Now we generate triangular synthesis window
129  tmpWindow.SetSize(mConfig.GetHopSize()*2+1);
130 
131  mPO_SynthWindowGen.Start();
132  mPO_SynthWindowGen.Do(tmpWindow);
133  mPO_SynthWindowGen.Stop();
134 
135 
136  //Now we multiply both windows
137  mPO_AudioProduct.Do(tmpWindow,mSynthWindow,mSynthWindow);
138 
139  //now we set it to even size leaving last sample out
140  mSynthWindow.SetSize(mConfig.GetHopSize()*2);
141 
142 
143 
144 }
145 
146 
147 bool SpectralSynthesis::ConcreteConfigure(const ProcessingConfig& c)
148 {
149  CopyAsConcreteConfig(mConfig, c);
150 
151  mConfig.Sync();
152 
153  mOutput.SetSize( mConfig.GetHopSize()*2 );
154  mOutput.SetHop( mConfig.GetHopSize()*2 );
155 
156 
157  //CONFIGURE CHILDREN AND DATA
158  ConfigureChildren();
159 
160  ConfigureData();
161  return true;
162 }
163 
165 {
166  bool result = Do(mInput.GetData(),mOutput.GetAudio());
167  mInput.Consume();
168  mOutput.Produce();
169  return result;
170 }
171 
172 
174 {
175 
176  TSize analWindowSize = mConfig.GetAnalWindowSize()-1;//note I include the minus 1!
177  TSize hopSize = mConfig.GetHopSize();
178 //Now we do the inverse FFT
179  mPO_IFFT.Do(in, mAudio0);
180 //Undoing Synthesis circular shift
181  mPO_CircularShift.Do(mAudio0,mAudio0);
182 //We take the central samples to multiply with the window while also undoing the zero padding
183  int centerSample = analWindowSize*0.5;
184  mAudio0.GetAudioChunk(centerSample-hopSize,centerSample+hopSize-1,mAudio2,false);
185 //Aplying inverse window
186  mPO_AudioProduct.Do(mAudio2, mSynthWindow,out);
187 
188 
189  return true;
190 }
191 
192 
194 {
195  if(mConfig.GetResidual())
196  return Do(in.GetSpectrum(),in.GetAudioFrame());
197  else
198  return Do(in.GetResidualSpec(),in.GetResidualAudioFrame());
199 }
200 
202 {
203  return Do(in.GetFrame(in.mCurrentFrameIndex++));
204 }
205 
206 TInt32 SpectralSynthesis::CalculatePowerOfTwo(TInt32 size)
207 {
208  int tmp = size;
209  int outputSize = 1;
210  while (tmp)
211  {
212  outputSize=outputSize << 1;
213  tmp=tmp >> 1;
214  }
215  if(outputSize == size << 1)
216  outputSize = outputSize >> 1;
217  return outputSize;
218 }
219 
220 
221 }
222