From 0182bbff2871114a4e93cc97942da621491f0e02 Mon Sep 17 00:00:00 2001 From: Thomas Grill Date: Tue, 7 Jan 2003 00:28:39 +0000 Subject: "" svn path=/trunk/; revision=325 --- externals/grill/fftease/src/burrow~.cpp | 255 ++++++++++++++++++++++++++++++++ 1 file changed, 255 insertions(+) create mode 100644 externals/grill/fftease/src/burrow~.cpp (limited to 'externals/grill/fftease/src/burrow~.cpp') diff --git a/externals/grill/fftease/src/burrow~.cpp b/externals/grill/fftease/src/burrow~.cpp new file mode 100644 index 00000000..7fbc45b8 --- /dev/null +++ b/externals/grill/fftease/src/burrow~.cpp @@ -0,0 +1,255 @@ +/* + +FFTease - A set of Live Spectral Processors +Originally written by Eric Lyon and Christopher Penrose for the Max/MSP platform + +This flext port is based on the jMax port of Christian Klippel + +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 burrow: + public flext_dsp +{ + FLEXT_HEADER_S(burrow,flext_dsp,setup) + +public: + burrow(I argc,const t_atom *argv); + ~burrow(); + +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); + + BL _invert; + I _inCount; + I *_bitshuffle; + + F _threshold,_multiplier; + F _thresh_dB,_mult_dB; + + F *_Wanal; + F *_Wsyn; + F *_inputOne,*_inputTwo; + F *_Hwin; + F *_bufferOne,*_bufferTwo; + F *_channelOne,*_channelTwo; + F *_output; + F *_trigland; + +private: + V Reset(); + V Clear(); + + V ms_thresh(F v) { _threshold = (float) (pow( 10., ((_thresh_dB = v) * .05))); } + V ms_mult(F v) { _multiplier = (float) (pow( 10., ((_mult_dB = v) * .05))); } + + + static V setup(t_classid c); + + FLEXT_ATTRGET_F(_thresh_dB) + FLEXT_CALLSET_F(ms_thresh) + FLEXT_ATTRGET_F(_mult_dB) + FLEXT_CALLSET_F(ms_mult) + FLEXT_ATTRVAR_B(_invert) +}; + +FLEXT_LIB_DSP_V("fftease, burrow~",burrow) + + +V burrow::setup(t_classid c) +{ + FLEXT_CADDATTR_VAR(c,"thresh",_thresh_dB,ms_thresh); + FLEXT_CADDATTR_VAR(c,"mult",_mult_dB,ms_mult); + FLEXT_CADDATTR_VAR1(c,"invert",_invert); +} + + +burrow::burrow(I argc,const t_atom *argv): + _thresh_dB(-30),_mult_dB(-18), + _invert(false) +{ + /* parse and set object's options given */ + if(argc >= 1) { + if(CanbeFloat(argv[0])) + _thresh_dB = GetAFloat(argv[0]); + else + post("%s - Threshold must be a float value - set to %0f",thisName(),_thresh_dB); + } + if(argc >= 2) { + if(CanbeFloat(argv[1])) + _mult_dB = GetAFloat(argv[1]); + else + post("%s - Multiplier must be a float value - set to %0f",thisName(),_mult_dB); + } + if(argc >= 3) { + if(CanbeBool(argv[2])) + _invert = GetABool(argv[2]); + else + post("%s - Invert flags must be a boolean value - set to %i",thisName(),_invert?1:0); + } + + ms_thresh(_thresh_dB); + ms_mult(_mult_dB); + + Reset(); + + AddInSignal(2); + AddOutSignal(); +} + +burrow::~burrow() +{ + Clear(); +} + +V burrow::Reset() +{ + _bitshuffle = NULL; + _trigland = NULL; + _inputOne = _inputTwo = NULL; + _Hwin = NULL; + _Wanal = _Wsyn = NULL; + _bufferOne = _bufferTwo = NULL; + _channelOne = _channelTwo = NULL; + _output = NULL; +} + +V burrow::Clear() +{ + if(_bitshuffle) delete[] _bitshuffle; + if(_trigland) delete[] _trigland; + if(_inputOne) delete[] _inputOne; + if(_inputTwo) delete[] _inputTwo; + if(_Hwin) delete[] _Hwin; + if(_Wanal) delete[] _Wanal; + if(_Wsyn) delete[] _Wsyn; + if(_bufferOne) delete[] _bufferOne; + if(_bufferTwo) delete[] _bufferTwo; + if(_channelOne) delete[] _channelOne; + if(_channelTwo) delete[] _channelTwo; + if(_output) delete[] _output; +} + + + +V burrow::m_dsp(I n,S *const *in,S *const *out) +{ + Clear(); + + /* preset the objects data */ + const I _D = Blocksize(); + const I _N = _D* 4,_Nw = _N,_N2 = _N / 2,_Nw2 = _Nw / 2; + + _inCount = -_Nw; + + /* assign memory to the buffers */ + _bitshuffle = new I[_N*2]; + _trigland = new F[_N*2]; + _inputOne = new F[_Nw]; + _inputTwo = new F[_Nw]; + _Hwin = new F[_Nw]; + _Wanal = new F[_Nw]; + _Wsyn = new F[_Nw]; + _bufferOne = new F[_N]; + _bufferTwo = new F[_N]; + _channelOne = new F[_N+2]; + _channelTwo = new F[_N+2]; + _output = new F[_Nw]; + + /* initialize pv-lib functions */ + init_rdft( _N, _bitshuffle, _trigland); + makewindows( _Hwin, _Wanal, _Wsyn, _Nw, _N, _D, 0); +} + +V burrow::m_signal(I n,S *const *in,S *const *out) +{ + const S *inOne = in[0],*inTwo = in[1]; + S *outOne = out[0]; + + /* declare working variables */ + I i, j, even, odd; + const I _D = Blocksize(); + const I _N = _D* 4,_Nw = _N,_N2 = _N / 2,_Nw2 = _Nw / 2; + + /* fill our retaining buffers */ + _inCount += _D; + + for(i = 0; i < _N-_D ; i++ ) { + _inputOne[i] = _inputOne[i+_D]; + _inputTwo[i] = _inputTwo[i+_D]; + } + for(j = 0; i < _N; i++,j++) { + _inputOne[i] = inOne[j]; + _inputTwo[i] = inTwo[j]; + } + + /* apply hamming window and fold our window buffer into the fft buffer */ + fold( _inputOne, _Wanal, _Nw, _bufferOne, _N, _inCount ); + fold( _inputTwo, _Wanal, _Nw, _bufferTwo, _N, _inCount ); + + /* do an fft */ + rdft( _N, 1, _bufferOne, _bitshuffle, _trigland ); + rdft( _N, 1, _bufferTwo, _bitshuffle, _trigland ); + + + /* convert to polar coordinates from complex values */ + for ( i = 0; i <= _N2; i++ ) { + register F a,b; + + odd = ( even = i<<1 ) + 1; + + a = ( i == _N2 ? _bufferOne[1] : _bufferOne[even] ); + b = ( i == 0 || i == _N2 ? 0. : _bufferOne[odd] ); + + _channelOne[even] = hypot( a, b ); + _channelOne[odd] = -atan2( b, a ); + + a = ( i == _N2 ? _bufferTwo[1] : _bufferTwo[even] ); + b = ( i == 0 || i == _N2 ? 0. : _bufferTwo[odd] ); + + _channelTwo[even] = hypot( a, b ); + + /* use simple threshold from second signal to trigger filtering */ + if (_invert?(_channelTwo[even] < _threshold):(_channelTwo[even] > _threshold) ) + _channelOne[even] *= _multiplier; + } + + /* convert back to complex form, read for the inverse fft */ + for ( i = 0; i <= _N2; i++ ) { + odd = ( even = i<<1 ) + 1; + + *(_bufferOne+even) = *(_channelOne+even) * cos( *(_channelOne+odd) ); + + if ( i != _N2 ) + *(_bufferOne+odd) = -(*(_channelOne+even)) * sin( *(_channelOne+odd) ); + } + + /* do an inverse fft */ + rdft( _N, -1, _bufferOne, _bitshuffle, _trigland ); + + /* dewindow our result */ + overlapadd( _bufferOne, _N, _Wsyn, _output, _Nw, _inCount); + + /* set our output and adjust our retaining output buffer */ + F mult = 1./_N; + for ( j = 0; j < _D; j++ ) + outOne[j] = _output[j] * mult; + + for ( j = 0; j < _N-_D; j++ ) + _output[j] = _output[j+_D]; + for (; j < _N; j++ ) + _output[j] = 0.; + + /* restore state variables */ +} + + + -- cgit v1.2.1