From cada39a002fbbe9bc848f963c3eb7faa65122228 Mon Sep 17 00:00:00 2001 From: Thomas Grill Date: Sun, 19 Jan 2003 21:11:59 +0000 Subject: "" svn path=/trunk/; revision=345 --- externals/grill/fftease/src/burrow~.cpp | 7 ++- externals/grill/fftease/src/convert.c | 84 +++++++++++++++++++++++++++++-- externals/grill/fftease/src/cross~.cpp | 58 ++++++++++++++++++--- externals/grill/fftease/src/dentist~.cpp | 22 ++++---- externals/grill/fftease/src/disarray~.cpp | 17 ++++--- externals/grill/fftease/src/drown~.cpp | 12 ++--- externals/grill/fftease/src/ether~.cpp | 5 +- externals/grill/fftease/src/fftease.cpp | 24 ++++++--- externals/grill/fftease/src/fold.c | 29 +++++++++++ externals/grill/fftease/src/leanconvert.c | 57 ++++++++++++++++++--- externals/grill/fftease/src/main.h | 10 ++-- externals/grill/fftease/src/morphine~.cpp | 15 +++--- externals/grill/fftease/src/pv.h | 2 +- externals/grill/fftease/src/scrape~.cpp | 27 ++++++---- externals/grill/fftease/src/shapee~.cpp | 21 +++++--- externals/grill/fftease/src/swinger~.cpp | 48 +++++++++--------- externals/grill/fftease/src/taint~.cpp | 7 ++- externals/grill/fftease/src/thresher~.cpp | 12 ++--- externals/grill/fftease/src/vacancy~.cpp | 34 ++++++++----- externals/grill/fftease/src/xsyn~.cpp | 10 ++-- 20 files changed, 360 insertions(+), 141 deletions(-) (limited to 'externals/grill/fftease/src') diff --git a/externals/grill/fftease/src/burrow~.cpp b/externals/grill/fftease/src/burrow~.cpp index 8398bbbb..fcfaf22e 100644 --- a/externals/grill/fftease/src/burrow~.cpp +++ b/externals/grill/fftease/src/burrow~.cpp @@ -55,7 +55,7 @@ V burrow::setup(t_classid c) burrow::burrow(I argc,const t_atom *argv): - fftease(4,F_STEREO|F_BALANCED|F_BITSHUFFLE|F_CONVERT), + fftease(4,F_STEREO|F_BALANCED|F_BITSHUFFLE|F_NOPH2), _thresh_dB(-30),_mult_dB(-18), _invert(false) { @@ -88,13 +88,12 @@ burrow::burrow(I argc,const t_atom *argv): } -V burrow::Transform(I _N2,S *const *in) +V burrow::Transform(I _N,S *const *in) { - const I _N = _N2*2; register const F thr = _threshold,mul = _multiplier; // use simple threshold from second signal to trigger filtering - // transform does not need phase of signal 2 (-> optimize it!) + // transform does not need phase of signal 2 if(_invert) for (I i = 0; i <= _N; i += 2) diff --git a/externals/grill/fftease/src/convert.c b/externals/grill/fftease/src/convert.c index 07500f90..006e4cf7 100644 --- a/externals/grill/fftease/src/convert.c +++ b/externals/grill/fftease/src/convert.c @@ -12,7 +12,8 @@ void convert(float *S, float *C, int N2, float *lastphase, float fundamental, float factor ) { - float phase, phasediff; +#if 1 + float phase,phasediff; int even,odd; float a,b; int i; @@ -26,20 +27,62 @@ void convert(float *S, float *C, int N2, float *lastphase, float fundamental, f if ( C[even] == 0. ) phasediff = 0.; else { - phasediff = ( phase = -atan2( b, a ) ) - lastphase[i]; + phase = -atan2( b, a ); + phasediff = fmod(phase - lastphase[i] + (PV_2PI+PV_PI), PV_2PI)-PV_PI; lastphase[i] = phase; - - while ( phasediff > PV_PI ) phasediff -= PV_2PI; - while ( phasediff < -PV_PI ) phasediff += PV_2PI; } C[odd] = phasediff*factor + i*fundamental; } +#else + float phase, + phasediff; + int real, + imag, + amp, + freq; + float a, + b; + int i; + + float myTWOPI, myPI; + + myTWOPI = 8.*atan(1.); + myPI = 4.*atan(1.); + + + for ( i = 0; i <= N2; i++ ) { + imag = freq = ( real = amp = i<<1 ) + 1; + a = ( i == N2 ? S[1] : S[real] ); + b = ( i == 0 || i == N2 ? 0. : S[imag] ); + + C[amp] = hypot( a, b ); + if ( C[amp] == 0. ) + phasediff = 0.; + else { + phasediff = ( phase = -atan2( b, a ) ) - lastphase[i]; + lastphase[i] = phase; + + // TG: DANGEROUS!!!! (and slow, if lastphase not correctly initialized) + while ( phasediff > myPI ) + phasediff -= myTWOPI; + while ( phasediff < -myPI ) + phasediff += myTWOPI; + } + C[freq] = phasediff*factor + i*fundamental; + /* + if( i > 8 && i < 12 ) { + fprintf(stderr,"convert freq %d: %f\n",i, C[freq]); + } + */ + } +#endif } void unconvert(float *C, float *S, int N2, float *lastphase, float fundamental, float factor ) { +#if 1 int i,even,odd; float mag,phase; @@ -57,4 +100,35 @@ void unconvert(float *C, float *S, int N2, float *lastphase, float fundamental, else S[1] = mag*cos( phase ); } +#else + int i, + real, + imag, + amp, + freq; + float mag, + phase; + + for ( i = 0; i <= N2; i++ ) { + + imag = freq = ( real = amp = i<<1 ) + 1; + + if ( i == N2 ) + real = 1; + + mag = C[amp]; + lastphase[i] += C[freq] - i*fundamental; + phase = lastphase[i]*factor; + S[real] = mag*cos( phase ); + + if ( i != N2 ) + S[imag] = -mag*sin( phase ); + /* + if( i == 10 ) { + fprintf(stderr,"unconvert: amp: %f freq: %f funda %f fac %f\n", C[amp],C[freq],fundamental,factor); + } + */ + } + +#endif } diff --git a/externals/grill/fftease/src/cross~.cpp b/externals/grill/fftease/src/cross~.cpp index e794d761..9b56d6e4 100644 --- a/externals/grill/fftease/src/cross~.cpp +++ b/externals/grill/fftease/src/cross~.cpp @@ -15,21 +15,39 @@ WARRANTIES, see the file, "license.txt," in this distribution. class cross: public fftease { - FLEXT_HEADER(cross,fftease) + FLEXT_HEADER_S(cross,fftease,setup) public: cross(); protected: + F *amps; + BL memory; + + virtual V Set(); + virtual V Clear(); + virtual V Delete(); + virtual V Transform(I _N2,S *const *in); + +private: + static V setup(t_classid c); + + FLEXT_ATTRVAR_B(memory) }; FLEXT_LIB_DSP("fftease, cross~",cross) +V cross::setup(t_classid c) +{ + FLEXT_CADDATTR_VAR1(c,"memorize",memory); +} + cross::cross(): - fftease(2,F_STEREO|F_BALANCED|F_BITSHUFFLE|F_CONVERT) + fftease(2,F_STEREO|F_BALANCED|F_BITSHUFFLE|F_NOPH2), + memory(true) { AddInSignal("Messages and driver signal"); AddInSignal("Filter signal"); @@ -37,14 +55,38 @@ cross::cross(): AddOutSignal("Transformed signal"); } -V cross::Transform(I _N2,S *const *in) +V cross::Clear() +{ + amps = NULL; + fftease::Clear(); +} + +V cross::Delete() +{ + fftease::Delete(); + if(amps) delete[] amps; +} + +V cross::Set() +{ + fftease::Set(); + const I _N2 = get_N()/2; + amps = new F[_N2]; + ZeroMem(amps,_N2*sizeof(*amps)); +} + +V cross::Transform(I _N,S *const *in) { // filled only once per signal vector!! register const F threshie = *in[0]; + F *amp = amps; + + for (I i = 0; i <= _N; i += 2,amp++) + if( _channel2[i] > threshie ) + *amp = _channel1[i] *= _channel2[i]; + else if(memory) + // retrieve previous value + _channel1[i] = *amp; - const I _N = _N2*2; - for (I i = 0; i <= _N; i += 2) { - // modulate amp2 with amp1 (if over threshold) - if(_channel1[i] > threshie ) _channel2[i] *= _channel1[i]; - } } + diff --git a/externals/grill/fftease/src/dentist~.cpp b/externals/grill/fftease/src/dentist~.cpp index 14a08688..ec854adf 100644 --- a/externals/grill/fftease/src/dentist~.cpp +++ b/externals/grill/fftease/src/dentist~.cpp @@ -24,7 +24,7 @@ protected: virtual V Transform(I _N2,S *const *in); - I *_bin_selection; + BL *_bin_selection; I _teeth; F _knee; I _max_bin; // determined by _knee and fundamental frequency @@ -63,7 +63,7 @@ V dentist::setup(t_classid c) dentist::dentist(I argc,const t_atom *argv): - fftease(4,F_BALANCED|F_BITSHUFFLE|F_CONVERT), + fftease(4,F_BALANCED|F_BITSHUFFLE), _knee(500),_teeth(10) { /* parse and set object's options given */ @@ -86,15 +86,13 @@ dentist::dentist(I argc,const t_atom *argv): V dentist::Clear() { - fftease::Clear(); - _bin_selection = NULL; + fftease::Clear(); } V dentist::Delete() { fftease::Delete(); - if(_bin_selection) delete[] _bin_selection; } @@ -119,17 +117,17 @@ V dentist::Set() { fftease::Set(); - _bin_selection = new I[get_N()/2]; + _bin_selection = new BL[get_N()/2]; // calculation of _max_bin ms_knee(_knee); } -V dentist::Transform(I _N2,S *const *in) +V dentist::Transform(I _N,S *const *in) { - for(I i = 0; i < _N2 ; i++){ - if( !_bin_selection[i] ) _channel1[i*2] = 0; - } + const BL *bs = _bin_selection; + for(I i = 0; i < _N ; i += 2) + if(!*(bs++)) _channel1[i] = 0; } @@ -145,7 +143,7 @@ V dentist::reset_shuffle() // clear and set random bins I i; for( i = 0; i < _N2; i++ ) - _bin_selection[i] = 0; + _bin_selection[i] = false; for( i = 0; i < t; i++ ) - _bin_selection[rand()%_max_bin] = 1; + _bin_selection[rand()%_max_bin] = true; } diff --git a/externals/grill/fftease/src/disarray~.cpp b/externals/grill/fftease/src/disarray~.cpp index e297131d..f9837408 100644 --- a/externals/grill/fftease/src/disarray~.cpp +++ b/externals/grill/fftease/src/disarray~.cpp @@ -53,13 +53,13 @@ V disarray::setup(t_classid c) { FLEXT_CADDBANG(c,0,reset_shuffle); - FLEXT_CADDATTR_VAR(c,"freq",_freq,ms_freq); - FLEXT_CADDATTR_VAR1(c,"shcnt",_shuffle_count); + FLEXT_CADDATTR_VAR(c,"knee",_freq,ms_freq); + FLEXT_CADDATTR_VAR1(c,"partials",_shuffle_count); } disarray::disarray(I argc,const t_atom *argv): - fftease(2,F_BITSHUFFLE|F_CONVERT), + fftease(2,F_BITSHUFFLE), _freq(1300),_qual(false),_shuffle_count(20) { /* parse and set object's options given */ @@ -79,7 +79,7 @@ disarray::disarray(I argc,const t_atom *argv): if(CanbeInt(argv[2])) _shuffle_count = GetAInt(argv[2]); else - post("%s - Shufflecount must be an integer value - set to %0i",thisName(),_shuffle_count); + post("%s - Partials must be an integer value - set to %0i",thisName(),_shuffle_count); } Mult(_qual?4:2); @@ -92,8 +92,8 @@ disarray::disarray(I argc,const t_atom *argv): V disarray::Clear() { - fftease::Clear(); _shuffle_in = _shuffle_out = NULL; + fftease::Clear(); } V disarray::Delete() @@ -134,13 +134,14 @@ V disarray::ms_freq(F f) inline V swap(F &a,F &b) { F t = a; a = b; b = t; } inline V swap(I &a,I &b) { I t = a; a = b; b = t; } -V disarray::Transform(I _N2,S *const *in) +V disarray::Transform(I _N,S *const *in) { I shcnt = _shuffle_count; if(shcnt < 0) shcnt = 0; - else if(shcnt > _N2) shcnt = _N2; + else if(shcnt > _N/2) shcnt = _N/2; for(I i = 0; i < shcnt; i++) + // leave phase, just swap amplitudes swap(_channel1[ _shuffle_in[i] * 2 ],_channel1[ _shuffle_out[i] * 2]); } @@ -153,7 +154,7 @@ V disarray::reset_shuffle() for( i = 0; i < _N2; i++ ) _shuffle_out[i] = _shuffle_in[i] = i ; - for( i = 0; i < 10000; i++ ) { + for( i = 0; i < _max_bin*2; i++ ) { I p1 = _shuffle_out[ rand()%_max_bin ]; I p2 = _shuffle_out[ rand()%_max_bin ]; swap(_shuffle_out[ p1 ],_shuffle_out[ p2 ]); diff --git a/externals/grill/fftease/src/drown~.cpp b/externals/grill/fftease/src/drown~.cpp index 171fbaf8..88803aa8 100644 --- a/externals/grill/fftease/src/drown~.cpp +++ b/externals/grill/fftease/src/drown~.cpp @@ -18,17 +18,17 @@ class drown: FLEXT_HEADER(drown,fftease) public: - drown(I argc,const t_atom *argv); + drown(); protected: virtual V Transform(I n,S *const *in); }; -FLEXT_LIB_DSP_V("fftease, drown~ denude~",drown) +FLEXT_LIB_DSP("fftease, drown~ denude~",drown) -drown::drown(I argc,const t_atom *argv): - fftease(4,F_BALANCED|F_CONVERT) +drown::drown(): + fftease(4,F_BALANCED) { AddInSignal("Messages and input signal"); AddInSignal("Threshold generator signal"); @@ -37,13 +37,11 @@ drown::drown(I argc,const t_atom *argv): } -V drown::Transform(I _N2,S *const *in) +V drown::Transform(I _N,S *const *in) { // only first value of the signal vectors const F thresh = *in[0],mult = *in[1]; - const I _N = _N2*2; - // make up low amplitude bins for (I i = 0; i <= _N; i += 2) if(_channel1[i] < thresh) _channel1[i] *= mult; diff --git a/externals/grill/fftease/src/ether~.cpp b/externals/grill/fftease/src/ether~.cpp index f75a6632..b8db17f8 100644 --- a/externals/grill/fftease/src/ether~.cpp +++ b/externals/grill/fftease/src/ether~.cpp @@ -46,7 +46,7 @@ V ether::setup(t_classid c) ether::ether(I argc,const t_atom *argv): - fftease(2,F_STEREO|F_BITSHUFFLE|F_CONVERT), + fftease(2,F_STEREO|F_BITSHUFFLE), _qual(false),_threshMult(0),_invert(false) { /* parse and set object's options given */ @@ -66,9 +66,8 @@ ether::ether(I argc,const t_atom *argv): } -V ether::Transform(I _N2,S *const *in) +V ether::Transform(I _N,S *const *in) { - const I _N = _N2*2; const BL inv = _invert; const F threshMult = _threshMult?_threshMult:1; diff --git a/externals/grill/fftease/src/fftease.cpp b/externals/grill/fftease/src/fftease.cpp index f67ed28f..5be59c0e 100644 --- a/externals/grill/fftease/src/fftease.cpp +++ b/externals/grill/fftease/src/fftease.cpp @@ -23,6 +23,7 @@ fftease::~fftease() {} BL fftease::Init() { Clear(); + Set(); return flext_dsp::Init(); } @@ -92,18 +93,18 @@ V fftease::m_signal(I n,S *const *in,S *const *out) if(_flags&F_STEREO) rfft( _buffer2, _N2,1); } - if(_flags&F_BITSHUFFLE) { - leanconvert( _buffer1, _channel1, _N2 ); - if(_flags&F_STEREO) leanconvert( _buffer2, _channel2, _N2 ); + if(!(_flags&F_NOSPEC)) { + leanconvert( _buffer1, _channel1, _N2 , !(_flags&F_NOAMP1),!(_flags&F_NOPH1)); + if(_flags&F_STEREO) leanconvert( _buffer2, _channel2, _N2 ,!(_flags&F_NOAMP2),!(_flags&F_NOPH2) ); } // ---- BEGIN -------------------------------- - Transform(_N2,in+((_flags&F_STEREO)?1:2)); + Transform(_N,in+((_flags&F_STEREO)?2:1)); // ---- END -------------------------------- - if(_flags&F_CONVERT) { + if(!(_flags&F_NOSPEC)) { leanunconvert( _channel1, _buffer1, _N2 ); if(_flags&F_STEREO) leanunconvert( _channel2, _buffer2, _N2 ); } @@ -139,14 +140,23 @@ void fftease::Set() /* assign memory to the buffers */ _input1 = new F[_Nw]; + ZeroMem(_input1,_Nw*sizeof(*_input1)); _buffer1 = new F[_N]; - if(_flags&(F_CONVERT|F_CRES)) _channel1 = new F[_N+2]; + if(!(_flags&F_NOSPEC) || (_flags&F_SPECRES)) { + _channel1 = new F[_N+2]; + ZeroMem(_channel1,(_N+2)*sizeof(*_channel1)); + } if(_flags&F_STEREO) { _input2 = new F[_Nw]; + ZeroMem(_input2,_Nw*sizeof(*_input2)); _buffer2 = new F[_N]; - if(_flags&(F_CONVERT|F_CRES)) _channel2 = new F[_N+2]; + if(!(_flags&F_NOSPEC) || (_flags&F_SPECRES)) { + _channel2 = new F[_N+2]; + ZeroMem(_channel2,(_N+2)*sizeof(*_channel2)); + } } _output = new F[_Nw]; + ZeroMem(_output,_Nw*sizeof(*_output)); if(_flags&F_BITSHUFFLE) { _bitshuffle = new I[_N*2]; diff --git a/externals/grill/fftease/src/fold.c b/externals/grill/fftease/src/fold.c index 2c380032..5b9ce476 100644 --- a/externals/grill/fftease/src/fold.c +++ b/externals/grill/fftease/src/fold.c @@ -6,6 +6,7 @@ */ void fold( float *I, float *W, int Nw, float *O, int N, int n ) { +#if 1 int i; for ( i = 0; i < N; i++ ) O[i] = 0.; @@ -16,6 +17,21 @@ void fold( float *I, float *W, int Nw, float *O, int N, int n ) O[n] += I[i]*W[i]; if ( ++n == N ) n = 0; } +#else + int i; + + for ( i = 0; i < N; i++ ) + O[i] = 0.; + + while ( n < 0 ) + n += N; + n %= N; + for ( i = 0; i < Nw; i++ ) { + O[n] += I[i]*W[i]; + if ( ++n == N ) + n = 0; + } +#endif } @@ -26,6 +42,7 @@ void fold( float *I, float *W, int Nw, float *O, int N, int n ) */ void overlapadd( float *I, int N, float *W, float *O, int Nw, int n ) { +#if 1 int i ; while ( n < 0 ) n += N ; n %= N ; @@ -34,5 +51,17 @@ void overlapadd( float *I, int N, float *W, float *O, int Nw, int n ) O[i] += I[n]*W[i] ; if ( ++n == N ) n = 0 ; } +#else + int i ; + while ( n < 0 ) + n += N ; + n %= N ; + for ( i = 0 ; i < Nw ; i++ ) { + O[i] += I[n]*W[i] ; + if ( ++n == N ) + n = 0 ; + } + +#endif } diff --git a/externals/grill/fftease/src/leanconvert.c b/externals/grill/fftease/src/leanconvert.c index ecb6bc54..0c567ca8 100644 --- a/externals/grill/fftease/src/leanconvert.c +++ b/externals/grill/fftease/src/leanconvert.c @@ -1,23 +1,49 @@ #include "pv.h" -void leanconvert( float *S, float *C, int N2 ) +void leanconvert( float *S, float *C, int N2 , int amp, int ph) { +#if 1 register int i; - float a = S[0]; // real value at f=0 - float b = S[1]; // real value at f=Nyquist + float a = fabs(S[0]); // real value at f=0 + float b = fabs(S[1]); // real value at f=Nyquist - C[0] = fabs(a); + C[0] = a; C[1] = 0; S += 2,C += 2; - for ( i = 1; i < N2; i++,S += 2,C += 2 ) { - C[0] = hypot( S[0], S[1] ); - C[1] = -atan2( S[1], S[0] ); + if(amp && ph) { + for ( i = 1; i < N2; i++,S += 2,C += 2 ) { + C[0] = hypot( S[0], S[1] ); + C[1] = -atan2( S[1], S[0] ); + } + } + else if(amp) { + for ( i = 1; i < N2; i++,S += 2,C += 2 ) + C[0] = hypot( S[0], S[1] ); + } + else if(ph) { + for ( i = 1; i < N2; i++,S += 2,C += 2 ) + C[1] = -atan2( S[1], S[0] ); } - C[0] = fabs(b); + C[0] = b; C[1] = 0; +#else + + int real, imag, + amp, phase; + float a, b; + int i; + + for ( i = 0; i <= N2; i++ ) { + imag = phase = ( real = amp = i<<1 ) + 1; + a = ( i == N2 ? S[1] : S[real] ); + b = ( i == 0 || i == N2 ? 0. : S[imag] ); + C[amp] = hypot( a, b ); + C[phase] = -atan2( b, a ); + } +#endif } @@ -29,6 +55,7 @@ void leanconvert( float *S, float *C, int N2 ) void leanunconvert( float *C, float *S, int N2 ) { +#if 1 register int i; S[0] = fabs(C[0]); @@ -39,5 +66,19 @@ void leanunconvert( float *C, float *S, int N2 ) S[0] = C[0] * cos( C[1] ); S[1] = -C[0] * sin( C[1] ); } +#else + int real, imag, + amp, phase; + float a, b; + register int i; + + for ( i = 0; i <= N2; i++ ) { + imag = phase = ( real = amp = i<<1 ) + 1; + S[real] = *(C+amp) * cos( *(C+phase) ); + if ( i != N2 ) + S[imag] = -*(C+amp) * sin( *(C+phase) ); + } + +#endif } diff --git a/externals/grill/fftease/src/main.h b/externals/grill/fftease/src/main.h index 0ee99584..3cbcc430 100644 --- a/externals/grill/fftease/src/main.h +++ b/externals/grill/fftease/src/main.h @@ -63,7 +63,7 @@ protected: virtual V Set(); virtual V Clear(); virtual V Delete(); - virtual V Transform(I _N2,S *const *in) = 0; + virtual V Transform(I _N,S *const *in) = 0; V Mult(I n) { _mult = n; MakeVar(); } @@ -83,8 +83,12 @@ protected: F_STEREO = 0x01, F_BALANCED = 0x02, F_BITSHUFFLE = 0x04, - F_CONVERT = 0x08,F_CRES = 0x10, - F_RMS = 0x20 + F_NOSPEC = 0x08,F_SPECRES = 0x10, + F_RMS = 0x20, + F_NOAMP1 = 0x100, + F_NOPH1 = 0x200, + F_NOAMP2 = 0x400, + F_NOPH2 = 0x800, }; I _flags; diff --git a/externals/grill/fftease/src/morphine~.cpp b/externals/grill/fftease/src/morphine~.cpp index 14ba0971..23c2cca9 100644 --- a/externals/grill/fftease/src/morphine~.cpp +++ b/externals/grill/fftease/src/morphine~.cpp @@ -51,8 +51,8 @@ V morphine::setup(t_classid c) morphine::morphine(I argc,const t_atom *argv): - fftease(4,F_STEREO|F_BALANCED|F_BITSHUFFLE|F_CONVERT), - _index(1) + fftease(4,F_STEREO|F_BALANCED|F_BITSHUFFLE), + _index(0) { /* parse and set object's options given */ if(argc >= 1) { @@ -69,8 +69,8 @@ morphine::morphine(I argc,const t_atom *argv): V morphine::Clear() { - fftease::Clear(); _picks = NULL; + fftease::Clear(); } V morphine::Delete() @@ -93,8 +93,9 @@ I morphine::sortpicks( const void *a, const void *b ) return 0; } -V morphine::Transform(I _N2,S *const *in) +V morphine::Transform(I _N,S *const *in) { + const I _N2 = _N/2; I i; for ( i = 0; i <= _N2; i++ ) { // find amplitude differences between home and visitors @@ -105,10 +106,12 @@ V morphine::Transform(I _N2,S *const *in) // sort our differences in ascending order qsort( _picks, _N2+1, sizeof(pickme), sortpicks ); - const I morphindex2 = (I)(_index*(_N2+1)+.5)*2; + I ix2 = (I)(_index*(_N2+1)+.5)*2; + if(ix2 < 0) ix2 = 0; + else if(ix2 > _N+2) ix2 = _N+2; // choose the bins that are least different first - for (i=0; i <= morphindex2; i += 2) { + for (i=0; i < ix2; i += 2) { _channel1[i] = _channel2[i]; _channel1[i+1] = _channel2[i+1]; } diff --git a/externals/grill/fftease/src/pv.h b/externals/grill/fftease/src/pv.h index 0927c17c..23fbd841 100644 --- a/externals/grill/fftease/src/pv.h +++ b/externals/grill/fftease/src/pv.h @@ -46,7 +46,7 @@ void fold( float *I, float *W, int Nw, float *O, int N, int n ); void overlapadd(float *I, int N, float *W, float *O, int Nw, int n ); void makehanning( float *H, float *A, float *S, int Nw, int N, int I, int osc, int odd ); void makewindows( float *H, float *A, float *S, int Nw, int N, int I, int osc ); -void leanconvert( float *S, float *C, int N2 ); +void leanconvert( float *S, float *C, int N2 , int amp, int ph ); void leanunconvert( float *C, float *S, int N2 ); void rfft( float *x, int N, int forward ); void cfft( float *x, int NC, int forward ); diff --git a/externals/grill/fftease/src/scrape~.cpp b/externals/grill/fftease/src/scrape~.cpp index e31374bd..04366614 100644 --- a/externals/grill/fftease/src/scrape~.cpp +++ b/externals/grill/fftease/src/scrape~.cpp @@ -39,11 +39,17 @@ private: inline V ms_knee(F knee) { _knee = knee; UpdThrFun(); } inline V ms_cutoff(F cutoff) { _cutoff = cutoff; UpdThrFun(); } + inline V ms_thresh1(F thr) { _thresh1 = thr; UpdThrFun(); } + inline V ms_thresh2(F thr) { _thresh2 = thr; UpdThrFun(); } FLEXT_ATTRGET_F(_knee) FLEXT_CALLSET_F(ms_knee) FLEXT_ATTRGET_F(_cutoff) FLEXT_CALLSET_F(ms_cutoff) + FLEXT_ATTRGET_F(_thresh1) + FLEXT_CALLSET_F(ms_thresh1) + FLEXT_ATTRGET_F(_thresh2) + FLEXT_CALLSET_F(ms_thresh2) }; FLEXT_LIB_DSP_V("fftease, scrape~",scrape) @@ -53,11 +59,13 @@ V scrape::setup(t_classid c) { FLEXT_CADDATTR_VAR(c,"knee",_knee,ms_knee); FLEXT_CADDATTR_VAR(c,"cutoff",_cutoff,ms_cutoff); + FLEXT_CADDATTR_VAR(c,"thresh1",_thresh1,ms_thresh1); + FLEXT_CADDATTR_VAR(c,"thresh2",_thresh2,ms_thresh2); } scrape::scrape(I argc,const t_atom *argv): - fftease(4,F_BALANCED|F_BITSHUFFLE|F_CONVERT), + fftease(4,F_BALANCED|F_BITSHUFFLE), _thresh1(.0001),_thresh2(.09), _knee(1000),_cutoff(4000) @@ -87,8 +95,8 @@ scrape::scrape(I argc,const t_atom *argv): V scrape::Clear() { - fftease::Clear(); _threshfunc = NULL; + fftease::Clear(); } V scrape::Delete() @@ -128,18 +136,19 @@ V scrape::UpdThrFun() \remark maxamp is calculated later than in the original FFTease scrape~ object */ -V scrape::Transform(I _N2,S *const *in) +V scrape::Transform(I _N,S *const *in) { const F fmult = *in[0]; + const F *thrf = _threshfunc; I i; F maxamp = 1.; - for( i = 0; i <= _N2; i++ ) - if(maxamp < _channel1[i*2]) - maxamp = _channel1[i*2]; + for( i = 0; i <= _N; i += 2 ) + if(maxamp < _channel1[i]) + maxamp = _channel1[i]; - for( i = 0; i <= _N2; i++ ) - if(_channel1[i*2] < _threshfunc[i] * maxamp) - _channel1[i*2] *= fmult; + for( i = 0; i <= _N; i += 2 ) + if(_channel1[i] < *(thrf++) * maxamp) + _channel1[i] *= fmult; } diff --git a/externals/grill/fftease/src/shapee~.cpp b/externals/grill/fftease/src/shapee~.cpp index 0af5aa93..b42ba46f 100644 --- a/externals/grill/fftease/src/shapee~.cpp +++ b/externals/grill/fftease/src/shapee~.cpp @@ -31,7 +31,7 @@ FLEXT_LIB_DSP_V("fftease, shapee~",shapee) shapee::shapee(I argc,const t_atom *argv): - fftease(2,F_STEREO|F_BITSHUFFLE|F_CONVERT), + fftease(2,F_STEREO|F_BITSHUFFLE), _qual(false) { /* parse and set object's options given */ @@ -54,16 +54,23 @@ shapee::shapee(I argc,const t_atom *argv): AddOutSignal("Transformed signal"); } +#define THRESH 0.000001 -V shapee::Transform(I _N2,S *const *in) +V shapee::Transform(I _N,S *const *in) { // lets just shape the entire signal in groups of three - const I _N = _N2*2; I i; - for ( i=2; i < _N+2; i += 6 ) { - F lowerMult = _channel1[i-2] / _channel1[i]; - F upperMult = _channel1[i+2] / _channel1[i]; + for ( i=2; i <= _N; i += 6 ) { + const F ref = _channel1[i]; + F lowerMult,upperMult; + + if(!ref) + lowerMult = upperMult = 1; + else { + lowerMult = _channel1[i-2] / ref; + upperMult = _channel1[i+2] / ref; + } F newCenter = ( _channel2[i-2]+_channel2[i]+_channel2[i+2] ) / (upperMult + lowerMult + 1); _channel2[i-2] = lowerMult * newCenter; @@ -71,7 +78,7 @@ V shapee::Transform(I _N2,S *const *in) _channel2[i] = newCenter; } - for ( i=0; i < _N; i+=2 ) { + for ( i=0; i <= _N; i+=2 ) { _channel1[i] = _channel2[i]; if ( _channel1[i] == 0. ) _channel1[i+1] = 0.; diff --git a/externals/grill/fftease/src/swinger~.cpp b/externals/grill/fftease/src/swinger~.cpp index b2ecba34..143bf5de 100644 --- a/externals/grill/fftease/src/swinger~.cpp +++ b/externals/grill/fftease/src/swinger~.cpp @@ -21,44 +21,44 @@ class swinger: FLEXT_HEADER(swinger,fftease) public: - swinger(); + swinger(I argc,const t_atom *argv); protected: + BL _qual; + virtual V Transform(I n,S *const *in); }; -FLEXT_LIB_DSP("fftease, swinger~",swinger) +FLEXT_LIB_DSP_V("fftease, swinger~",swinger) -swinger::swinger(): - fftease(2,F_STEREO|F_BITSHUFFLE) +swinger::swinger(I argc,const t_atom *argv): + fftease(2,F_STEREO|F_BITSHUFFLE|F_NOPH1|F_NOAMP2), + _qual(false) { + /* parse and set object's options given */ + if(argc >= 1) { + if(CanbeBool(argv[0])) + _qual = GetABool(argv[0]); + else + post("%s - Quality must be a boolean value - set to %0i",thisName(),_qual?1:0); + } + + if(_qual) { + Mult(4); + _flags |= F_BALANCED; + } + else + Mult(2); + AddInSignal("Messages and input signal"); AddInSignal("Signal to supply phase information"); AddOutSignal("Transformed signal"); } -V swinger::Transform(I _N2,S *const *in) +V swinger::Transform(I _N,S *const *in) { - for (I i = 0; i <= _N2; i++ ) { - const I even = i*2,odd = even+1; - - // convert to polar coordinates from complex values - // replace signal one's phases with those of signal two - const F a1 = ( i == _N2 ? _buffer1[1] : _buffer1[even] ); - const F b1 = ( i == 0 || i == _N2 ? 0. : _buffer1[odd] ); - // amplitude only - const F amp = hypot( a1, b1 ); - - const F a2 = ( i == _N2 ? _buffer2[1] : _buffer2[even] ); - const F b2 = ( i == 0 || i == _N2 ? 0. : _buffer2[odd] ); - // phase only - const F ph = -atan2( b2, a2 ); - - _buffer1[even] = amp * cos( ph ); - if ( i != _N2 ) - _buffer1[odd] = -amp * sin( ph ); - } + for (I i = 0; i <= _N; i += 2) _channel1[i+1] = _channel2[i+1]; } diff --git a/externals/grill/fftease/src/taint~.cpp b/externals/grill/fftease/src/taint~.cpp index 18b7c076..82c38f0e 100644 --- a/externals/grill/fftease/src/taint~.cpp +++ b/externals/grill/fftease/src/taint~.cpp @@ -42,13 +42,13 @@ FLEXT_LIB_DSP_V("fftease, taint~",taint) V taint::setup(t_classid c) { - FLEXT_CADDATTR_VAR(c,"threshold",_threshdB,ms_thresh); + FLEXT_CADDATTR_VAR(c,"thresh",_threshdB,ms_thresh); FLEXT_CADDATTR_VAR1(c,"invert",_invert); } taint::taint(I argc,const t_atom *argv): - fftease(4,F_STEREO|F_BALANCED|F_BITSHUFFLE|F_CONVERT), + fftease(4,F_STEREO|F_BALANCED|F_BITSHUFFLE|F_NOPH2), _threshdB(-10),_invert(false) { /* parse and set object's options given */ @@ -74,9 +74,8 @@ taint::taint(I argc,const t_atom *argv): } -V taint::Transform(I _N2,S *const *in) +V taint::Transform(I _N,S *const *in) { - const I _N = _N2*2; register const F thr = _threshold; if(_invert) { diff --git a/externals/grill/fftease/src/thresher~.cpp b/externals/grill/fftease/src/thresher~.cpp index 241dad12..2f186c92 100644 --- a/externals/grill/fftease/src/thresher~.cpp +++ b/externals/grill/fftease/src/thresher~.cpp @@ -57,7 +57,9 @@ void thresher::Set() _compositeFrame = new F[_N+2]; _framesLeft = new I[_N2+1]; _c_lastphase_in = new F[_N2+1]; + ZeroMem(_c_lastphase_in,(_N2+1)*sizeof(*_c_lastphase_in)); _c_lastphase_out = new F[_N2+1]; + ZeroMem(_c_lastphase_out,(_N2+1)*sizeof(*_c_lastphase_out)); _c_fundamental = _R/_N; _c_factor_in = _R/(_D * PV_2PI); @@ -88,18 +90,16 @@ void thresher::Delete() thresher::thresher(): - fftease(4,F_BALANCED|F_BITSHUFFLE|F_CRES) + fftease(4,F_BALANCED|F_BITSHUFFLE|F_NOSPEC|F_SPECRES) { AddInSignal("Messages and input signal"); AddOutSignal("Transformed signal"); } -V thresher::Transform(I _N2,S *const *in) +V thresher::Transform(I _N,S *const *in) { - const I _N = _N2*2; - - convert( _buffer1, _channel1, _N2, _c_lastphase_in, _c_fundamental, _c_factor_in ); + convert( _buffer1, _channel1, _N/2, _c_lastphase_in, _c_fundamental, _c_factor_in ); I *fr = _framesLeft; if( _firstFrame ) { @@ -122,5 +122,5 @@ V thresher::Transform(I _N2,S *const *in) } } - unconvert( _compositeFrame, _buffer1, _N2, _c_lastphase_out, _c_fundamental, _c_factor_out ); + unconvert( _compositeFrame, _buffer1, _N/2, _c_lastphase_out, _c_fundamental, _c_factor_out ); } diff --git a/externals/grill/fftease/src/vacancy~.cpp b/externals/grill/fftease/src/vacancy~.cpp index 4377290d..881a3ca2 100644 --- a/externals/grill/fftease/src/vacancy~.cpp +++ b/externals/grill/fftease/src/vacancy~.cpp @@ -24,6 +24,7 @@ protected: virtual V Transform(I n,S *const *in); V ms_thresh(F thr) { _threshold = FromdB(_threshdB = thr); } + V ms_userms(BL r) { if(r) _flags |= F_RMS; else _flags &= ~F_RMS; } F _threshold,_threshdB; BL _invert,_useRms,_swapPhase; @@ -34,7 +35,8 @@ private: FLEXT_ATTRGET_F(_threshdB) FLEXT_CALLSET_F(ms_thresh) FLEXT_ATTRVAR_B(_invert) - FLEXT_ATTRVAR_B(_useRms) + FLEXT_ATTRGET_B(_useRms) + FLEXT_CALLSET_B(ms_userms) FLEXT_ATTRVAR_B(_swapPhase) }; @@ -43,15 +45,15 @@ FLEXT_LIB_DSP_V("fftease, vacancy~",vacancy) V vacancy::setup(t_classid c) { - FLEXT_CADDATTR_VAR(c,"threshold",_threshdB,ms_thresh); + FLEXT_CADDATTR_VAR(c,"thresh",_threshdB,ms_thresh); FLEXT_CADDATTR_VAR1(c,"invert",_invert); - FLEXT_CADDATTR_VAR1(c,"rms",_useRms); - FLEXT_CADDATTR_VAR1(c,"swapphase",_swapPhase); + FLEXT_CADDATTR_VAR(c,"rms",_useRms,ms_userms); + FLEXT_CADDATTR_VAR1(c,"swap",_swapPhase); } vacancy::vacancy(I argc,const t_atom *argv): - fftease(2,F_BITSHUFFLE|F_CONVERT), + fftease(2,F_STEREO|F_BITSHUFFLE), _threshdB(-30),_invert(false),_useRms(true),_swapPhase(false) { /* parse and set object's options given */ @@ -84,6 +86,7 @@ vacancy::vacancy(I argc,const t_atom *argv): } ms_thresh(_threshdB); + ms_userms(_useRms); AddInSignal("Messages and input signal"); AddInSignal("Reference signal"); @@ -91,36 +94,41 @@ vacancy::vacancy(I argc,const t_atom *argv): } -V vacancy::Transform(I _N2,S *const *in) +V vacancy::Transform(I _N,S *const *in) { const F useme = _useRms?_rms * _threshold:_threshold; - const I _N = _N2; // composite here please - if (_invert) - if (_swapPhase) + if (_invert) { + if (_swapPhase) { for (I i=0; i < _N; i+=2 ) if ( _channel1[i] > useme && _channel2[i] < _channel1[i] ) { _channel1[i] = _channel2[i]; _channel1[i+1] = _channel2[i+1]; } - else + } + else { for (I i=0; i < _N; i+=2 ) if ( _channel1[i] > useme && _channel2[i] < _channel1[i] ) { _channel1[i] = _channel2[i]; if ( _channel1[i+1] == 0. ) _channel1[i+1] = _channel2[i+1]; } - else - if (_swapPhase) + } + } + else { + if (_swapPhase) { for (I i=0; i < _N; i+=2 ) if ( _channel1[i] < useme && _channel2[i] > _channel1[i] ) { _channel1[i] = _channel2[i]; _channel1[i+1] = _channel2[i+1]; } - else + } + else { for (I i=0; i < _N; i+=2 ) if ( _channel1[i] < useme && _channel2[i] > _channel1[i] ) { _channel1[i] = _channel2[i]; if ( _channel1[i+1] == 0. ) _channel1[i+1] = _channel2[i+1]; } + } + } } diff --git a/externals/grill/fftease/src/xsyn~.cpp b/externals/grill/fftease/src/xsyn~.cpp index e509c827..89e84868 100644 --- a/externals/grill/fftease/src/xsyn~.cpp +++ b/externals/grill/fftease/src/xsyn~.cpp @@ -28,7 +28,7 @@ FLEXT_LIB_DSP("fftease, xsyn~",xsyn) xsyn::xsyn(): - fftease(2,F_STEREO|F_BITSHUFFLE|F_CONVERT) + fftease(2,F_STEREO|F_BITSHUFFLE|F_NOPH2) { AddInSignal("Messages and source signal 1"); AddInSignal("Source signal 2"); @@ -36,17 +36,15 @@ xsyn::xsyn(): } -V xsyn::Transform(I _N2,S *const *in) +V xsyn::Transform(I _N,S *const *in) { - const I _N = _N2*2; - F maxamp = 0; I i; - for( i = 0; i < _N; i+= 2 ) + for( i = 0; i <= _N; i+= 2 ) if(_channel2[i] > maxamp ) maxamp = _channel2[i]; const F f = maxamp?1./maxamp:1.; - for( i = 0; i < _N; i+= 2 ) + for( i = 0; i <= _N; i+= 2 ) _channel1[i] *= (_channel2[i] * f); } -- cgit v1.2.1