diff options
author | Thomas Grill <xovo@users.sourceforge.net> | 2003-01-08 04:37:20 +0000 |
---|---|---|
committer | Thomas Grill <xovo@users.sourceforge.net> | 2003-01-08 04:37:20 +0000 |
commit | 900871454af06db1d751e28cea56f59dc43d3c17 (patch) | |
tree | f0056d2f328953865d8882a6c8c5e3c673cf1254 /externals/grill/fftease/src/cross~.cpp | |
parent | b8510c87be3a74307f4ad6122d75a353d350b84c (diff) |
""
svn path=/trunk/; revision=328
Diffstat (limited to 'externals/grill/fftease/src/cross~.cpp')
-rw-r--r-- | externals/grill/fftease/src/cross~.cpp | 236 |
1 files changed, 236 insertions, 0 deletions
diff --git a/externals/grill/fftease/src/cross~.cpp b/externals/grill/fftease/src/cross~.cpp new file mode 100644 index 00000000..52874127 --- /dev/null +++ b/externals/grill/fftease/src/cross~.cpp @@ -0,0 +1,236 @@ +/* + +FFTease - A set of Live Spectral Processors +Originally written by Eric Lyon and Christopher Penrose for the Max/MSP platform + +Copyright (c)Thomas Grill (xovo@gmx.net) +For information on usage and redistribution, and for a DISCLAIMER OF ALL +WARRANTIES, see the file, "license.txt," in this distribution. + +*/ + +#include "main.h" + + +class cross: + public flext_dsp +{ + FLEXT_HEADER_S(cross,flext_dsp,setup) + +public: + cross(I argc,const t_atom *argv); + ~cross(); + +protected: + + virtual V m_dsp(I n,S *const *in,S *const *out); + virtual V m_signal(I n,S *const *in,S *const *out); + + I blsz; + F smprt; + + F *_input1,*_input2; + F *_buffer1,*_buffer2; + F *_channel1,*_channel2; + F *_output; + F *_trigland; + I *_bitshuffle; + F *_Wanal,*_Wsyn,*_Hwin; + + I _inCount; + +private: + enum { _MULT_ = 2 }; + + V Clear(); + V Delete(); + + static V setup(t_classid c); +}; + +FLEXT_LIB_DSP_V("fftease, cross~",cross) + + +V cross::setup(t_classid c) +{ +} + + +cross::cross(I argc,const t_atom *argv): + blsz(0),smprt(0) +{ + Clear(); + + AddInSignal("Messages and driver signal"); + AddInSignal("Filter signal"); + AddInSignal("Threshold signal for cross synthesis"); + AddOutSignal("Transformed signal"); +} + +cross::~cross() +{ + Delete(); +} + +V cross::Clear() +{ + _input1 = _input2 = NULL; + _buffer1 = _buffer2 = NULL; + _channel1 = _channel2 = NULL; + _output = NULL; + + _bitshuffle = NULL; + _trigland = NULL; + + _Hwin = NULL; + _Wanal = _Wsyn = NULL; +} + +V cross::Delete() +{ + if(_input1) delete[] _input1; + if(_input2) delete[] _input2; + if(_buffer1) delete[] _buffer1; + if(_buffer2) delete[] _buffer2; + if(_channel1) delete[] _channel1; + if(_channel2) delete[] _channel2; + if(_output) delete[] _output; + + if(_bitshuffle) delete[] _bitshuffle; + if(_trigland) delete[] _trigland; + + if(_Wanal) delete[] _Wanal; + if(_Wsyn) delete[] _Wsyn; + if(_Hwin) delete[] _Hwin; + + // --------------------------------------------- + +#if 0 + // T.G. These are not used + if(c_lastphase_in1) delete[] c_lastphase_in1; + if(c_lastphase_in2) delete[] c_lastphase_in2; + if(c_lastphase_out) delete[] c_lastphase_out; +#endif +} + + + +V cross::m_dsp(I n,S *const *in,S *const *out) +{ + const I _D = Blocksize(); + const F _R = Samplerate(); + + if(_D != blsz || _R != smprt) { + blsz = _D; + smprt = _R; + + Delete(); + + const int _N = _D*_MULT_,_Nw = _N,_N2 = _N>>1,_Nw2 = _Nw>>1; + + _inCount = -_Nw; + + _input1 = new F[_Nw]; + _input2 = new F[_Nw]; + _buffer1 = new F[_N]; + _buffer2 = new F[_N]; + _channel1 = new F[_N+2]; + _channel2 = new F[_N+2]; + _output = new F[_Nw]; + + _bitshuffle = new I[_N*2]; + _trigland = new F[_N*2]; + + _Wanal = new F[_Nw]; + _Wsyn = new F[_Nw]; + _Hwin = new F[_Nw]; + + init_rdft( _N, _bitshuffle, _trigland); + + // makewindows( x->Hwin, x->Wanal, x->Wsyn, x->Nw, x->N, x->D, 0); + makehanning( _Hwin, _Wanal, _Wsyn, _Nw, _N, _D, 0,0); + + // --------------------------------------------- + +#if 0 + // T.G. These are not used + /* for convert */ + c_lastphase_in1 = new F[_N2+1]; + c_lastphase_in2 = new F[_N2+1]; + c_lastphase_out = new F[_N2+1]; + c_fundamental = _R/( _N2<<1 ); + c_factor_in = _R/(_D * __TWOPI); + c_factor_out = __TWOPI * _D/_R; +#endif + } +} + +V cross::m_signal(I n,S *const *in,S *const *out) +{ + /* declare working variables */ + I i, j; + const I _D = blsz,_N = _D*_MULT_,_Nw = _N,_N2 = _N/2,_Nw2 = _Nw/2; + + _inCount += _D; + + for ( j = 0 ; j < _N-_D ; j++ ) { + _input1[j] = _input1[j+_D]; + _input2[j] = _input2[j+_D]; + } + for (i = 0; j < _N; j++,i++ ) { + _input1[j] = in[0][i]; + _input2[j] = in[1][i]; + } + + fold( _input1, _Wanal, _Nw, _buffer1, _N, _inCount ); + fold( _input2, _Wanal, _Nw, _buffer2, _N, _inCount ); + + rdft( _N, 1, _buffer1, _bitshuffle, _trigland ); + rdft( _N, 1, _buffer2, _bitshuffle, _trigland ); + + + // ---- BEGIN -------------------------------- + + // TG: filled only once per signal vector!! + float threshie = *in[2]; + + for ( i = 0; i <= _N2; i++ ) { + const I even = i<<1,odd = even+1; + + F a = ( i == _N2 ? _buffer1[1] : _buffer2[even] ); + F b = ( i == 0 || i == _N2 ? 0. : _buffer2[odd] ); + F gainer = hypot( a, b ) ; + + a = ( i == _N2 ? _buffer1[1] : _buffer1[even] ); + b = ( i == 0 || i == _N2 ? 0. : _buffer1[odd] ); + + if( gainer > threshie ) + _channel1[even] = hypot( a, b ) * gainer; + // else + // channel1[even] = hypot( a, b); + + _channel1[odd] = -atan2( b, a ); + _buffer1[even] = _channel1[even] * cos( _channel1[odd] ); + + if ( i != _N2 ) + _buffer1[odd] = -_channel1[even] * sin( _channel1[odd] ); + } + + // ---- END -------------------------------- + + rdft( _N, -1, _buffer1, _bitshuffle, _trigland ); + + overlapadd( _buffer1, _N, _Wsyn, _output, _Nw, _inCount); + + const F mult = 1./_N; + for ( j = 0; j < _D; j++ ) + out[0][j] = _output[j] * mult; + + for ( j = 0; j < _N-_D; j++ ) + _output[j] = _output[j+_D]; + for (; j < _N; j++ ) + _output[j] = 0.; +} + + + |