From e1bdd67199e389a5ba7eb03ecff171058c37a467 Mon Sep 17 00:00:00 2001 From: Thomas Grill Date: Thu, 23 Jan 2003 08:53:05 +0000 Subject: "" svn path=/trunk/; revision=357 --- externals/grill/fftease/pd/thresher.pd | 18 +++-- externals/grill/fftease/readme.txt | 9 ++- externals/grill/fftease/src/fftease.cpp | 64 ++++++++++----- externals/grill/fftease/src/main.h | 9 ++- externals/grill/fftease/src/pvoc~.cpp | 128 ++++++++++++++++++++++++++++++ externals/grill/fftease/src/thresher~.cpp | 26 ++---- 6 files changed, 201 insertions(+), 53 deletions(-) create mode 100644 externals/grill/fftease/src/pvoc~.cpp (limited to 'externals/grill') diff --git a/externals/grill/fftease/pd/thresher.pd b/externals/grill/fftease/pd/thresher.pd index 13201212..d34d4f46 100644 --- a/externals/grill/fftease/pd/thresher.pd +++ b/externals/grill/fftease/pd/thresher.pd @@ -1,17 +1,17 @@ -#N canvas 140 138 626 392 12; +#N canvas 140 138 585 330 12; #X obj 17 86 tgl 20 1 empty empty enable_dsp 0 -6 0 10 -225271 -1 -1 1 1; #X msg 17 111 enable \$1; -#X obj 219 288 *~; -#X obj 260 293 hsl 128 15 0.001 10 1 1 empty empty volume -2 -6 0 10 +#X obj 219 248 *~; +#X obj 260 253 hsl 128 15 0.001 10 1 1 empty empty volume -2 -6 0 10 -261681 -1 -1 10300 1; -#X obj 208 325 dac~; +#X obj 208 285 dac~; #X obj 16 8 cnv 15 550 40 empty empty thresher~ 10 22 0 24 -260818 -1 0; #X text 206 7 FFTease (C)Lyon \, Penrose (for Max/MSP); #X text 206 27 flext port by Thomas Grill; -#X obj 467 297 print A; -#X text 464 316 attributes; +#X obj 327 217 print A; +#X text 391 216 attributes; #X obj 219 92 bng 25 250 50 0 empty empty start 0 -6 0 8 -261689 -1 -1; #N canvas 35 47 460 310 nixon 0; @@ -31,8 +31,10 @@ #X connect 5 1 4 0; #X connect 5 2 1 0; #X connect 6 0 1 0; -#X restore 219 184 pd nixon; -#X obj 218 227 thresher~; +#X restore 219 144 pd nixon; +#X obj 218 187 thresher~; +#X obj 18 250 nacho~; +#X text 17 274 alternative name; #X connect 0 0 1 0; #X connect 1 0 12 0; #X connect 2 0 4 0; diff --git a/externals/grill/fftease/readme.txt b/externals/grill/fftease/readme.txt index fefd498f..2ca7b808 100644 --- a/externals/grill/fftease/readme.txt +++ b/externals/grill/fftease/readme.txt @@ -55,13 +55,15 @@ You must have the following "Source Trees" defined: PORTING NOTES: -The example audio files schubert.aiff and nixon.aiff have been thankfully taken from -Christian Klippels FFTease jMax port. +The example audio files schubert.aiff and nixon.aiff have been taken from the original FFTease package for Max/MSP. - pv-lib: - gcc (OSX) complains about _cfft being defined by pv-lib and pd.... any problems with that? +- burrow: + - max_bin calculation: fundamental frequency seems to be wrong + - cross: - STRANGE: spectral amplitude in channel1 is undefined if gainer <= threshie -> value of previous frame is used then @@ -73,7 +75,8 @@ Christian Klippels FFTease jMax port. - use different knee correction - disarray: - - different frequency correction + - different frequency correction employed + - max_bin calculation: fundamental frequency seems to be wrong - check whether freq oder number of bins should be selectable -> frequency! - ether: diff --git a/externals/grill/fftease/src/fftease.cpp b/externals/grill/fftease/src/fftease.cpp index 6d1da836..23d07491 100644 --- a/externals/grill/fftease/src/fftease.cpp +++ b/externals/grill/fftease/src/fftease.cpp @@ -95,8 +95,14 @@ V fftease::m_signal(I n,S *const *in,S *const *out) } 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) ); + if(_flags&F_PHCONV) { + convert( _buffer1, _channel1, _N2, _c_lastphase_in1, get_Fund(), _c_factor_in ); + if(_flags&F_STEREO) convert( _buffer2, _channel2, _N2, _c_lastphase_in2, get_Fund(), _c_factor_in ); + } + else { + 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 -------------------------------- @@ -106,8 +112,10 @@ V fftease::m_signal(I n,S *const *in,S *const *out) // ---- END -------------------------------- if(!(_flags&F_NOSPEC)) { - leanunconvert( _channel1, _buffer1, _N2 ); - if(_flags&F_STEREO) leanunconvert( _channel2, _buffer2, _N2 ); + if(_flags&F_PHCONV) + unconvert( _channel1, _buffer1, _N2, _c_lastphase_out, get_Fund(), 1./_c_factor_in ); + else + leanunconvert( _channel1, _buffer1, _N2 ); } @@ -135,7 +143,7 @@ V fftease::m_signal(I n,S *const *in,S *const *out) void fftease::Set() { /* preset the objects data */ - const I _D = Blocksize(),_N = _D*Mult(),_Nw = _N; //,_N2 = _N/2,_Nw2 = _Nw/2; + const I _D = Blocksize(),_N = _D*Mult(),_Nw = _N,_N2 = _N/2; //,_Nw2 = _Nw/2; _inCount = -_Nw; @@ -143,19 +151,34 @@ void fftease::Set() _input1 = new F[_Nw]; ZeroMem(_input1,_Nw*sizeof(*_input1)); _buffer1 = new F[_N]; - 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_NOSPEC) || (_flags&F_SPECRES)) { + } + + if(!(_flags&F_NOSPEC) || (_flags&F_SPECRES)) { + _channel1 = new F[_N+2]; + ZeroMem(_channel1,(_N+2)*sizeof(*_channel1)); + if(_flags&F_STEREO) { _channel2 = new F[_N+2]; ZeroMem(_channel2,(_N+2)*sizeof(*_channel2)); } + + if(_flags&F_PHCONV) { + _c_lastphase_in1 = new F[_N2+1]; + ZeroMem(_c_lastphase_in1,(_N2+1)*sizeof(*_c_lastphase_in1)); + if(_flags&F_STEREO) { + _c_lastphase_in2 = new F[_N2+1]; + ZeroMem(_c_lastphase_in2,(_N2+1)*sizeof(*_c_lastphase_in2)); + } + _c_lastphase_out = new F[_N2+1]; + ZeroMem(_c_lastphase_out,(_N2+1)*sizeof(*_c_lastphase_out)); + + _c_factor_in = Samplerate()/(_D * PV_2PI); + } } + _output = new F[_Nw]; ZeroMem(_output,_Nw*sizeof(*_output)); @@ -184,6 +207,8 @@ void fftease::Clear() _buffer1 = _buffer2 = NULL; _channel1 = _channel2 = NULL; _output = NULL; + + _c_lastphase_in1 = _c_lastphase_in2 = _c_lastphase_out = NULL; } void fftease::Delete() @@ -191,17 +216,18 @@ void fftease::Delete() if(_input1) delete[] _input1; if(_buffer1) delete[] _buffer1; if(_channel1) delete[] _channel1; - if(_flags&F_STEREO) { - if(_input2) delete[] _input2; - if(_buffer2) delete[] _buffer2; - if(_channel2) delete[] _channel2; - } + if(_input2) delete[] _input2; + if(_buffer2) delete[] _buffer2; + if(_channel2) delete[] _channel2; + + if(_c_lastphase_in1) delete[] _c_lastphase_in1; + if(_c_lastphase_in2) delete[] _c_lastphase_in2; + if(_c_lastphase_out) delete[] _c_lastphase_out; + if(_output) delete[] _output; - if(_flags&F_BITSHUFFLE) { - if(_bitshuffle) delete[] _bitshuffle; - if(_trigland) delete[] _trigland; - } + if(_bitshuffle) delete[] _bitshuffle; + if(_trigland) delete[] _trigland; if(_Hwin) delete[] _Hwin; if(_Wanal) delete[] _Wanal; diff --git a/externals/grill/fftease/src/main.h b/externals/grill/fftease/src/main.h index de2356ad..9f016115 100644 --- a/externals/grill/fftease/src/main.h +++ b/externals/grill/fftease/src/main.h @@ -50,7 +50,7 @@ public: static F FromdB(F v) { return pow(10.,v*.05); } inline I get_N() const { return _N; } - inline F get_Fund() const { return smprt/(_N*2); } + inline F get_Fund() const { return smprt/_N; } protected: @@ -77,14 +77,17 @@ protected: I *_bitshuffle; F *_Wanal,*_Wsyn,*_Hwin; + F *_c_lastphase_in1,*_c_lastphase_in2,*_c_lastphase_out; + F _c_factor_in; + I _inCount; enum { F_STEREO = 0x01, F_BALANCED = 0x02, F_BITSHUFFLE = 0x04, - F_NOSPEC = 0x08,F_SPECRES = 0x10, - F_RMS = 0x20, + F_RMS = 0x08, + F_NOSPEC = 0x10,F_SPECRES = 0x20,F_PHCONV = 0x40, F_NOAMP1 = 0x100, F_NOPH1 = 0x200, F_NOAMP2 = 0x400, diff --git a/externals/grill/fftease/src/pvoc~.cpp b/externals/grill/fftease/src/pvoc~.cpp new file mode 100644 index 00000000..d17cc576 --- /dev/null +++ b/externals/grill/fftease/src/pvoc~.cpp @@ -0,0 +1,128 @@ +/* + +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 pvoc: + public fftease +{ + FLEXT_HEADER_S(pvoc,fftease,setup) + +public: + pvoc(I argc,const t_atom *argv); + +protected: + + virtual V Transform(I _N2,S *const *in); + + BL _invert; + + F _threshold,_multiplier; + F _thresh_dB,_mult_dB; + +private: + V ms_thresh(F v) { _threshold = FromdB(_thresh_dB = v); } + V ms_mult(F v) { _multiplier = FromdB(_mult_dB = v); } + + + 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, pvoc~",pvoc) + + +V pvoc::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); +} + + +pvoc::pvoc(I argc,const t_atom *argv): + fftease(4,F_STEREO|F_BALANCED|F_BITSHUFFLE|F_NOPH2), + _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 flag must be a boolean value - set to %i",thisName(),_invert?1:0); + } + + ms_thresh(_thresh_dB); + ms_mult(_mult_dB); + + AddInSignal("Messages and input signal"); + AddInSignal("Reference signal"); + AddOutSignal("Transformed signal"); +} + + +V pvoc::Transform(I _N,S *const *in) +{ + int freq,amp; + int chan; + + // start osc bank + for ( chan = lo_bin; chan < hi_bin; chan++ ) { + freq = ( amp = ( chan << 1 ) ) + 1; + if ( _channel1[amp] < synt ){ + breaker = 1; + } + if( breaker ) { + breaker = 0 ; + } + else { + _channel1[freq] *= myPInc; + finc = ( _channel1[freq] - ( f = lastfreq[chan] ) )*Iinv; + ainc = ( _channel1[amp] - ( a = lastamp[chan] ) )*Iinv; + address = index[chan]; + for ( n = 0; n < I; n++ ) { + output[n] += a*table[ (int) address ]; + address += f; + while ( address >= L ) + address -= L; + while ( address < 0 ) + address += L; + a += ainc; + f += finc; + } + lastfreq[chan] = _channel1[freq]; + lastamp[chan] = _channel1[amp]; + index[chan] = address; + } + } +} + + + diff --git a/externals/grill/fftease/src/thresher~.cpp b/externals/grill/fftease/src/thresher~.cpp index 2f186c92..98c02eb1 100644 --- a/externals/grill/fftease/src/thresher~.cpp +++ b/externals/grill/fftease/src/thresher~.cpp @@ -29,8 +29,6 @@ protected: F *_compositeFrame; I *_framesLeft; - F *_c_lastphase_in,*_c_lastphase_out; - F _c_fundamental,_c_factor_in,_c_factor_out; BL _firstFrame; F _moveThreshold; @@ -40,7 +38,7 @@ private: static V setup(t_classid c); }; -FLEXT_LIB_DSP("fftease, thresher~",thresher) +FLEXT_LIB_DSP("fftease, thresher~ nacho~",thresher) V thresher::setup(t_classid c) @@ -56,14 +54,6 @@ 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); - _c_factor_out = 1./_c_factor_in; _firstFrame = true; _moveThreshold = .00001 ; @@ -76,7 +66,6 @@ void thresher::Clear() fftease::Clear(); _compositeFrame = NULL; _framesLeft = NULL; - _c_lastphase_in = _c_lastphase_out = NULL; } void thresher::Delete() @@ -84,13 +73,11 @@ void thresher::Delete() fftease::Delete(); if(_compositeFrame) delete[] _compositeFrame; if(_framesLeft) delete[] _framesLeft; - if(_c_lastphase_in) delete[] _c_lastphase_in; - if(_c_lastphase_out) delete[] _c_lastphase_out; } thresher::thresher(): - fftease(4,F_BALANCED|F_BITSHUFFLE|F_NOSPEC|F_SPECRES) + fftease(4,F_BALANCED|F_BITSHUFFLE|F_PHCONV) { AddInSignal("Messages and input signal"); AddOutSignal("Transformed signal"); @@ -99,8 +86,6 @@ thresher::thresher(): V thresher::Transform(I _N,S *const *in) { - convert( _buffer1, _channel1, _N/2, _c_lastphase_in, _c_fundamental, _c_factor_in ); - I *fr = _framesLeft; if( _firstFrame ) { for (I i = 0; i <= _N; i += 2,++fr ){ @@ -117,10 +102,11 @@ V thresher::Transform(I _N,S *const *in) _compositeFrame[i+1] = _channel1[i+1]; *fr = _maxHoldFrames; } - else + else { + _channel1[i] = _compositeFrame[i]; + _channel1[i+1] = _compositeFrame[i+1]; --*fr; + } } } - - unconvert( _compositeFrame, _buffer1, _N/2, _c_lastphase_out, _c_fundamental, _c_factor_out ); } -- cgit v1.2.1