00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011 #ifndef INCLUDE_CONVOLUTION_H
00012 #define INCLUDE_CONVOLUTION_H
00013
00014 #include "CSL_Core.h"
00015 #include "Spectral.h"
00016
00018
00019 #define CHECK_PTR(ptr) \
00020 if (!ptr) throw MemoryError("Can't allocate buffer")
00021
00022 #define initvec( name, size, type ) \
00023 if ((name = (type *) calloc(size, sizeof(type))) == NULL) \
00024 throw MemoryError("Can't allocate buffer");
00025
00026 #define cmac(in1, in2, out) \
00027 out[0] += in1[0] * in2[0] - in1[1] * in2[1]; \
00028 out[1] += in1[0] * in2[1] + in1[1] * in2[0];
00029
00030 #define cbinc(buf, size) if (++buf > size-1) buf = 0;
00031 #define cbdec(buf, size) if (--buf < 0) buf = size - 1;
00032
00033 #define cbarb(buf, size, amt) \
00034 buf += amt; \
00035 if (buf >= size) buf -= size; \
00036 else if (buf < 0) buf += size;
00037
00038 namespace csl {
00039
00043
00044
00045 class Convolver : public Effect {
00046
00047 public:
00048 Convolver() : Effect() {};
00049 Convolver(char *IRfilename);
00050 Convolver(unsigned len, Buffer & impulseResp);
00051 Convolver(unsigned len, char * IRfilename);
00052 Convolver(Buffer & inbuf);
00053 ~Convolver();
00055 void initialize(Buffer & buf) throw (CException);
00056 void setFilters(fftwf_complex ** filterFFTs);
00057 void setInputf(fftwf_complex * inFFT);
00058 CSL_FFTW_sample * mSampleBuffer;
00059
00061 void nextBuffer(Buffer &outputBuffer, unsigned outBufNum) throw (CException);
00062
00063 protected:
00064 CSL_FFTW_cmplx ** mFilterFFTs;
00065 CSL_FFTW_cmplx ** mInputFFTs;
00066 CSL_FFTW_cmplx * mSpectrumBuffer;
00067 CSL_FFTW_plan mForwardPlan, mInversePlan;
00068 unsigned mFFTSize, mWindowCount, mNumBufs;
00069 bool mMyBuffers;
00070 bool mMyInput;
00071
00072 void initialize (const char *filename) throw (CException);
00073
00074
00075
00076
00077 inline void complex_multiply_accumulate(CSL_FFTW_cmplx * left, CSL_FFTW_cmplx * right, CSL_FFTW_cmplx * output) {
00078 CSL_FFTW_cmplx * loleft = left;
00079 CSL_FFTW_cmplx * loright = right;
00080 CSL_FFTW_cmplx * looutput = output;
00081 float re, im;
00082 float leftRe, rightRe, leftIm, rightIm;
00083 unsigned frame = mFFTSize;
00084
00085 while (frame--) {
00086 leftRe = (*loleft)[0];
00087 rightRe = (*loright)[0];
00088 leftIm = (*loleft)[1];
00089 rightIm = (*loright)[1];
00090 re = (leftRe * rightRe) - (leftIm * rightIm);
00091 im = (leftRe * rightIm) + (leftIm * rightRe);
00092 (*looutput)[0] += re;
00093 (*looutput)[1] += im;
00094 loleft++;
00095 loright++;
00096 looutput++;
00097 }
00098 }
00099
00100 };
00101
00102 }
00103
00104 #endif