IFFT_ooura.cxx
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #include "IFFT_ooura.hxx"
00024 #include "FFT_ooura.hxx"
00025
00026 #include "Assert.hxx"
00027 #include "Audio.hxx"
00028 #include "Spectrum.hxx"
00029 #include "SpectrumConfig.hxx"
00030 #include "CLAM_Math.hxx"
00031 #include "ProcessingFactory.hxx"
00032
00033 namespace CLAM {
00034
00035 namespace Hidden
00036 {
00037 static const char * metadata[] = {
00038 "key", "IFFT_ooura",
00039 "category", "Synthesis",
00040 "description", "IFFT_ooura",
00041 0
00042 };
00043 static FactoryRegistrator<ProcessingFactory, IFFT_ooura> reg = metadata;
00044 }
00045
00046
00047 bool IFFT_ooura::ConcreteConfigure(const ProcessingConfig& c) {
00048 int oldSize=mSize;
00049 CopyAsConcreteConfig(mConfig, c);
00050 if (mConfig.HasAudioSize()) {
00051 CLAM_ASSERT (mConfig.GetAudioSize()>=0,"Wrong (negative) Size in IFFT Configuration.");
00052 mSize = mConfig.GetAudioSize();
00053 if(mSize>0)
00054 {
00055 mOutput.SetSize( mSize );
00056 mOutput.SetHop( mSize );
00057 }
00058 }
00059 else
00060 mSize = CLAM_DEFAULT_IFFT_SIZE;
00061
00062 mState=sOther;
00063 mComplexflags.bComplex=1;
00064 mComplexflags.bMagPhase=0;
00065 if (mSize>0) {
00066 delete [] ifftbuffer;
00067 ifftbuffer = new TData[mSize];
00068 }
00069 else ifftbuffer = 0;
00070
00071 if ( !isPowerOfTwo( mSize ) )
00072 {
00073 AddConfigErrorMessage("Configure failed: IFFT Ooura algorithm only works for input buffers that are a power of two!");
00074 return false;
00075 }
00076 if (mSize>0) {
00077 if (mSize != oldSize) {
00078 ReleaseMemory();
00079 SetupMemory();
00080 }
00081 return true;
00082 }
00083 ReleaseMemory();
00084 return false;
00085 }
00086
00087 void IFFT_ooura::ReleaseMemory() {
00088 if (ip) { delete[] ip; ip = 0; }
00089 if (w) { delete[] w; w = 0; }
00090 }
00091
00092 void IFFT_ooura::SetupMemory() {
00093 int ipSize = (int)(2+(1<<(int)(log(mSize/2+0.5)/log(2.0))/2));
00094 ip = new int[ipSize];
00095 for (int i=0; i<ipSize; i++) ip[i] = 0;
00096
00097 int wSize = (int)(mSize*5/8-1);
00098 w = new TData[wSize];
00099 for (int i=0; i<wSize; i++) w[i] = 0;
00100 }
00101
00102 IFFT_ooura::IFFT_ooura()
00103 : ip(0), w(0)
00104 {
00105 Configure(IFFTConfig());
00106 }
00107
00108 IFFT_ooura::IFFT_ooura(const IFFTConfig &c) throw(ErrDynamicType)
00109 : ip(0), w(0)
00110 {
00111 Configure(c);
00112 };
00113
00114 IFFT_ooura::~IFFT_ooura()
00115 {
00116 ReleaseMemory();
00117 }
00118
00119 bool IFFT_ooura::Do()
00120 {
00121 bool toReturn = Do(mInput.GetData(),mOutput.GetAudio());
00122 mInput.Consume();
00123 mOutput.Produce();
00124 return toReturn;
00125 }
00126
00127 bool IFFT_ooura::Do(const Spectrum& in, Audio &out) const{
00128 TData* outbuffer = out.GetBuffer().GetPtr();
00129 int i;
00130
00131 CLAM_DEBUG_ASSERT(IsRunning(),
00132 "IFFT_ooura: Do(): Not in execution mode");
00133
00134 CLAM_DEBUG_ASSERT(isPowerOfTwo(mSize),
00135 "IFFT_ooura: Do(): Not a power of two");
00136
00137 out.SetSampleRate(in.GetSpectralRange()*2);
00138
00139 TData twoOverSize = 2.0/mSize;
00140
00141 switch(mState) {
00142 case sComplex:
00143 ComplexToIFFTOoura(in);
00144 FFT_ooura::rdft(mSize, -1, ifftbuffer, ip, w);
00145
00146
00147
00148 for (i=0; i<mSize; i++)
00149 outbuffer[i]=ifftbuffer[i]*twoOverSize;
00150 break;
00151 case sOther:
00152 OtherToIFFTOoura(in);
00153 FFT_ooura::rdft(mSize, -1, ifftbuffer, ip, w);
00154
00155
00156
00157 for (i=0; i<mSize; i++)
00158 outbuffer[i]=ifftbuffer[i]*twoOverSize;
00159
00160 break;
00161 default:
00162 CLAM_ASSERT(false, "IFFT_ooura: Do(): Inconsistent state");
00163 }
00164
00165 return true;
00166 }
00167
00168 void IFFT_ooura::ComplexToIFFTOoura(const Spectrum &in) const {
00169 int i;
00170 Array<Complex> inbuffer = in.GetComplexArray();
00171
00172 ifftbuffer[0] = inbuffer[0].Real();
00173 ifftbuffer[1] = inbuffer[mSize/2].Real();
00174
00175 for (i=1; i<mSize/2; i++) {
00176 ifftbuffer[2*i] = inbuffer[i].Real();
00177 ifftbuffer[2*i+1] = -inbuffer[i].Imag();
00178 }
00179 }
00180
00181 inline void IFFT_ooura::OtherToIFFTOoura(const Spectrum &in) const
00182 {
00183 SpecTypeFlags flags;
00184 in.GetType(flags);
00185
00186
00187
00188
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198
00199
00200
00201
00202
00203
00204 Spectrum tmpSpec = in;
00205 if (!in.HasComplexArray()) {
00206 flags.bComplex=1;
00207 tmpSpec.SetTypeSynchronize(flags);
00208 }
00209 ComplexToIFFTOoura(tmpSpec);
00210
00211
00212 }
00213
00214 bool IFFT_ooura::SetPrototypes(const Spectrum& in, const Audio &out)
00215 {
00216 CheckTypes(in,out);
00217
00218 SpecTypeFlags flags;
00219 in.GetType(flags);
00220
00221 if (flags.bComplex)
00222 mState=sComplex;
00223 else
00224 {
00225 CLAM_ASSERT(flags.bPolar || flags.bMagPhase || flags.bMagPhaseBPF,"IFFT_ooura: SetPrototypes(): No Spectrum Attributes!");
00226 mState=sOther;
00227 }
00228
00229
00230 return true;
00231 }
00232
00233 bool IFFT_ooura::SetPrototypes()
00234 {
00235
00236
00237 CLAM_ASSERT(false,"IFFT_ooura::SetPrototypes: Not implemented.");
00238 return false;
00239 }
00240
00241 bool IFFT_ooura::UnsetPrototypes()
00242 {
00243 mState=sOther;
00244 return true;
00245 }
00246
00247 void IFFT_ooura::CheckTypes(const Spectrum& in, const Audio &out) const
00248 {
00249 CLAM_ASSERT(out.HasBuffer(),"IFFT Do: Float attribute required for Audio object.");
00250 CLAM_BEGIN_CHECK
00251
00252 if (out.GetSize()!=mSize) {
00253 std::stringstream ss;
00254 ss << "IFFT_ooura::Do: Wrong size in IFFT Audio output\n"
00255 << " Expected: " << mSize*2+1 << ", used " << out.GetSize();
00256 CLAM_ASSERT(0,ss.str().c_str());
00257 }
00258 if (in.GetSize() < mSize/2+1 ) {
00259 std::stringstream ss;
00260 ss << "IFFT_ooura::Do: not enough memory in input Spectrum.\n"
00261 << " Expected: " << mSize/2+1 << ", used " << in.GetSize();
00262 CLAM_ASSERT(0,ss.str().c_str());
00263
00264 }
00265 CLAM_END_CHECK
00266 }
00267
00268
00269
00270
00271 };
00272