From 9ff5ccdea43ff2a954c1a400516dc6858e188e9c Mon Sep 17 00:00:00 2001 From: Thomas Grill Date: Sat, 18 Jan 2003 04:35:33 +0000 Subject: "" svn path=/trunk/; revision=344 --- externals/grill/fftease/fftease.dsp | 18 +----- externals/grill/fftease/make-files.txt | 3 +- externals/grill/fftease/pd/burrow.pd | 89 +++++++++++++++-------------- externals/grill/fftease/pd/cross.pd | 31 ++++++++++ externals/grill/fftease/pd/dentist.pd | 40 +++++++++++++ externals/grill/fftease/pd/disarray.pd | 41 +++++++++++++ externals/grill/fftease/pd/ether.pd | 39 +++++++++++++ externals/grill/fftease/src/burrow~.cpp | 43 +++++--------- externals/grill/fftease/src/convert.c | 85 ++++++++++++++------------- externals/grill/fftease/src/convert_new.c | 65 --------------------- externals/grill/fftease/src/cross~.cpp | 36 +++--------- externals/grill/fftease/src/dentist~.cpp | 40 ++++++------- externals/grill/fftease/src/disarray~.cpp | 29 +++++----- externals/grill/fftease/src/drown~.cpp | 30 +++------- externals/grill/fftease/src/ether~.cpp | 39 ++++--------- externals/grill/fftease/src/fft.c | 22 +++---- externals/grill/fftease/src/fftease.cpp | 9 +-- externals/grill/fftease/src/fold.c | 32 ++++++++--- externals/grill/fftease/src/leanconvert.c | 48 ++++++++++++---- externals/grill/fftease/src/leanunconvert.c | 23 -------- externals/grill/fftease/src/main.h | 16 +++++- externals/grill/fftease/src/makewindows.c | 34 ++++------- externals/grill/fftease/src/morphine~.cpp | 15 +++-- externals/grill/fftease/src/overlapadd.c | 17 ------ externals/grill/fftease/src/pv.h | 4 ++ externals/grill/fftease/src/scrape~.cpp | 13 ++--- externals/grill/fftease/src/shapee~.cpp | 8 ++- externals/grill/fftease/src/swinger~.cpp | 2 + externals/grill/fftease/src/taint~.cpp | 33 ++++++----- externals/grill/fftease/src/thresher~.cpp | 25 ++++---- externals/grill/fftease/src/unconvert.c | 36 ------------ externals/grill/fftease/src/vacancy~.cpp | 11 ++-- externals/grill/fftease/src/xsyn~.cpp | 2 +- 33 files changed, 481 insertions(+), 497 deletions(-) create mode 100644 externals/grill/fftease/pd/cross.pd create mode 100644 externals/grill/fftease/pd/dentist.pd create mode 100644 externals/grill/fftease/pd/disarray.pd create mode 100644 externals/grill/fftease/pd/ether.pd delete mode 100644 externals/grill/fftease/src/convert_new.c delete mode 100644 externals/grill/fftease/src/leanunconvert.c delete mode 100644 externals/grill/fftease/src/overlapadd.c delete mode 100644 externals/grill/fftease/src/unconvert.c diff --git a/externals/grill/fftease/fftease.dsp b/externals/grill/fftease/fftease.dsp index 650e35ff..f817f356 100644 --- a/externals/grill/fftease/fftease.dsp +++ b/externals/grill/fftease/fftease.dsp @@ -53,7 +53,7 @@ BSC32=bscmake.exe # ADD BSC32 /nologo LINK32=link.exe # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winsfftease.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 -# ADD LINK32 kernel32.lib user32.lib pd.lib ../flext_sh/pd-msvc/t/flext.lib /nologo /dll /machine:I386 /out:"pd-msvc/fftease.dll" /libpath:"c:\programme\audio\pd\bin" /libpath:"f:\prog\max\flext\pd-msvc" +# ADD LINK32 kernel32.lib user32.lib pd.lib flext-pdwin.lib /nologo /dll /machine:I386 /out:"pd-msvc/fftease.dll" /libpath:"c:\programme\audio\pd\bin" /libpath:"f:\prog\max\flext\pd-msvc" !ELSEIF "$(CFG)" == "fftease - Win32 Debug" @@ -96,10 +96,6 @@ SOURCE=.\src\convert.c # End Source File # Begin Source File -SOURCE=.\src\convert_new.c -# End Source File -# Begin Source File - SOURCE=.\src\fft.c # End Source File # Begin Source File @@ -116,24 +112,12 @@ SOURCE=.\src\leanconvert.c # End Source File # Begin Source File -SOURCE=.\src\leanunconvert.c -# End Source File -# Begin Source File - SOURCE=.\src\makewindows.c # End Source File # Begin Source File -SOURCE=.\src\overlapadd.c -# End Source File -# Begin Source File - SOURCE=.\src\pv.h # End Source File -# Begin Source File - -SOURCE=.\src\unconvert.c -# End Source File # End Group # Begin Group "objects" diff --git a/externals/grill/fftease/make-files.txt b/externals/grill/fftease/make-files.txt index 004b9b06..41dd636a 100644 --- a/externals/grill/fftease/make-files.txt +++ b/externals/grill/fftease/make-files.txt @@ -1,7 +1,6 @@ # all the source files from the package SRCS= \ - convert.c convert_new.c fft4.c fft.c fold.c \ - leanconvert.c leanunconvert.c makewindows.c overlapadd.c unconvert.c \ + makewindows.c fold.c convert.c leanconvert.c fft4.c fft.c \ main.cpp fftease.cpp \ burrow~.cpp cross~.cpp dentist~.cpp disarray~.cpp drown~.cpp ether~.cpp \ morphine~.cpp scrape~.cpp shapee~.cpp swinger~.cpp taint~.cpp \ diff --git a/externals/grill/fftease/pd/burrow.pd b/externals/grill/fftease/pd/burrow.pd index 076e4225..8b66f0f5 100644 --- a/externals/grill/fftease/pd/burrow.pd +++ b/externals/grill/fftease/pd/burrow.pd @@ -1,44 +1,45 @@ -#N canvas 398 240 590 356 12; -#X msg 17 161 getattributes; -#X obj 304 235 print A; -#X obj 161 210 burrow~ -30 -18 0; -#X obj 17 78 tgl 20 1 empty empty enable_dsp 0 -6 32 10 -225271 -1 --1 0 1; -#X msg 17 103 enable \$1; -#X obj 184 78 tgl 20 0 empty empty inverse_filtering 0 -6 32 10 -225271 --1 -1 0 1; -#X msg 184 102 invert \$1; -#X obj 373 78 nbx 5 18 -100 0 0 0 empty empty filtering_threshold(dB) -0 -6 32 10 -225271 -1 -1 -3 256; -#X msg 373 100 thresh \$1; -#X obj 374 145 nbx 5 18 -100 0 0 0 empty empty filter_multiplier(dB) -0 -6 32 10 -225271 -1 -1 0 256; -#X msg 374 167 mult \$1; -#X obj 162 275 *~; -#X obj 203 280 hsl 128 15 0.001 1 1 1 empty empty volume -2 -6 32 10 --261681 -1 -1 0 1; -#X obj 151 312 dac~; -#X obj 162 162 adc~ 1; -#X text 303 254 print attributes; -#X text 15 143 list attributes; -#X obj 292 162 adc~ 2; -#X obj 16 8 cnv 15 550 40 empty empty burrow~ 10 22 32 24 -260818 -1 -0; -#X text 188 8 FFTease (C)Lyon \, Penrose (for Max/MSP); -#X text 188 28 flext port by Thomas Grill; -#X connect 0 0 2 0; -#X connect 2 0 11 0; -#X connect 2 1 1 0; -#X connect 3 0 4 0; -#X connect 4 0 2 0; -#X connect 5 0 6 0; -#X connect 6 0 2 0; -#X connect 7 0 8 0; -#X connect 8 0 2 0; -#X connect 9 0 10 0; -#X connect 10 0 2 0; -#X connect 11 0 13 0; -#X connect 11 0 13 1; -#X connect 12 0 11 1; -#X connect 14 0 2 0; -#X connect 17 0 2 1; +#N canvas 398 240 594 360 12; +#X msg 17 161 getattributes; +#X obj 391 278 print A; +#X obj 161 210 burrow~ -30 -18 0; +#X obj 17 78 tgl 20 1 empty empty enable_dsp 0 -6 0 10 -225271 -1 -1 +1 1; +#X msg 17 103 enable \$1; +#X obj 184 78 tgl 20 0 empty empty inverse_filtering 0 -6 0 10 -225271 +-1 -1 1 1; +#X msg 184 102 invert \$1; +#X obj 373 78 nbx 5 18 -100 0 0 0 empty empty filtering_threshold(dB) +0 -6 0 10 -225271 -1 -1 -82 256; +#X msg 373 100 thresh \$1; +#X obj 374 145 nbx 5 18 -100 0 0 0 empty empty filter_multiplier(dB) +0 -6 0 10 -225271 -1 -1 -12 256; +#X msg 374 167 mult \$1; +#X obj 161 275 *~; +#X obj 202 280 hsl 128 15 0.001 10 1 1 empty empty volume -2 -6 0 10 +-261681 -1 -1 8000 1; +#X obj 150 312 dac~; +#X obj 162 162 adc~ 1; +#X text 390 297 print attributes; +#X text 15 143 list attributes; +#X obj 16 8 cnv 15 550 40 empty empty burrow~ 10 22 0 24 -260818 -1 +0; +#X text 188 8 FFTease (C)Lyon \, Penrose (for Max/MSP); +#X text 188 28 flext port by Thomas Grill; +#X obj 292 162 adc~ 2; +#X text 222 231 threshold \, multiplier \, invert; +#X connect 0 0 2 0; +#X connect 2 0 11 0; +#X connect 2 1 1 0; +#X connect 3 0 4 0; +#X connect 4 0 2 0; +#X connect 5 0 6 0; +#X connect 6 0 2 0; +#X connect 7 0 8 0; +#X connect 8 0 2 0; +#X connect 9 0 10 0; +#X connect 10 0 2 0; +#X connect 11 0 13 0; +#X connect 11 0 13 1; +#X connect 12 0 11 1; +#X connect 14 0 2 0; +#X connect 20 0 2 1; diff --git a/externals/grill/fftease/pd/cross.pd b/externals/grill/fftease/pd/cross.pd new file mode 100644 index 00000000..9801cf09 --- /dev/null +++ b/externals/grill/fftease/pd/cross.pd @@ -0,0 +1,31 @@ +#N canvas 140 138 596 362 12; +#X obj 17 78 tgl 20 1 empty empty enable_dsp 0 -6 0 10 -225271 -1 -1 +1 1; +#X msg 17 103 enable \$1; +#X obj 284 86 nbx 5 18 -100 0 0 0 empty empty threshold(dB) 0 -6 0 +10 -225271 -1 -1 0 256; +#X obj 161 275 *~; +#X obj 202 280 hsl 128 15 0.001 10 1 1 empty empty volume -2 -6 0 10 +-261681 -1 -1 8500 1; +#X obj 150 312 dac~; +#X obj 16 8 cnv 15 550 40 empty empty cross~ 10 22 0 24 -260818 -1 +0; +#X text 188 8 FFTease (C)Lyon \, Penrose (for Max/MSP); +#X text 188 28 flext port by Thomas Grill; +#X obj 161 210 cross~; +#X obj 284 163 sig~; +#X obj 283 115 + 100; +#X obj 284 138 dbtorms; +#X obj 162 162 adc~ 1 2; +#X connect 0 0 1 0; +#X connect 1 0 9 0; +#X connect 2 0 11 0; +#X connect 3 0 5 0; +#X connect 3 0 5 1; +#X connect 4 0 3 1; +#X connect 9 0 3 0; +#X connect 10 0 9 2; +#X connect 11 0 12 0; +#X connect 12 0 10 0; +#X connect 13 0 9 0; +#X connect 13 1 9 1; diff --git a/externals/grill/fftease/pd/dentist.pd b/externals/grill/fftease/pd/dentist.pd new file mode 100644 index 00000000..5bcabbd3 --- /dev/null +++ b/externals/grill/fftease/pd/dentist.pd @@ -0,0 +1,40 @@ +#N canvas 140 138 598 364 12; +#X obj 17 78 tgl 20 1 empty empty enable_dsp 0 -6 0 10 -225271 -1 -1 +1 1; +#X msg 17 103 enable \$1; +#X obj 374 91 nbx 5 18 0 20000 0 0 empty empty knee_frq 0 -6 0 10 -225271 +-1 -1 1375 256; +#X obj 211 272 *~; +#X obj 252 277 hsl 128 15 0.001 10 1 1 empty empty volume -2 -6 0 10 +-261681 -1 -1 10200 1; +#X obj 200 309 dac~; +#X obj 16 8 cnv 15 550 40 empty empty dentist~ 10 22 0 24 -260818 -1 +0; +#X text 198 8 FFTease (C)Lyon \, Penrose (for Max/MSP); +#X text 198 28 flext port by Thomas Grill; +#X msg 14 181 getattributes; +#X obj 432 255 print A; +#X obj 294 90 bng 25 250 50 0 empty empty reshuffle 0 -6 0 8 -225271 +-1 -1; +#X msg 374 123 knee \$1; +#X obj 452 91 nbx 5 18 0 1000 0 0 empty empty teeth 0 -6 0 10 -225271 +-1 -1 6 256; +#X msg 452 123 teeth \$1; +#X text 343 207 knee frq. \, teeth; +#X obj 211 207 dentist~ 1000 10; +#X obj 211 84 adc~ 1; +#X text 14 164 list attributes; +#X connect 0 0 1 0; +#X connect 1 0 16 0; +#X connect 2 0 12 0; +#X connect 3 0 5 0; +#X connect 3 0 5 1; +#X connect 4 0 3 1; +#X connect 9 0 16 0; +#X connect 11 0 16 0; +#X connect 12 0 16 0; +#X connect 13 0 14 0; +#X connect 14 0 16 0; +#X connect 16 0 3 0; +#X connect 16 1 10 0; +#X connect 17 0 16 0; diff --git a/externals/grill/fftease/pd/disarray.pd b/externals/grill/fftease/pd/disarray.pd new file mode 100644 index 00000000..3bdd36b4 --- /dev/null +++ b/externals/grill/fftease/pd/disarray.pd @@ -0,0 +1,41 @@ +#N canvas 140 138 600 366 12; +#X obj 17 78 tgl 20 1 empty empty enable_dsp 0 -6 0 10 -225271 -1 -1 +1 1; +#X msg 17 103 enable \$1; +#X obj 369 88 nbx 5 18 0 20000 0 0 empty empty knee_frq 0 -6 0 10 -225271 +-1 -1 0 256; +#X obj 211 272 *~; +#X obj 252 277 hsl 128 15 0.001 10 1 1 empty empty volume -2 -6 0 10 +-261681 -1 -1 8600 1; +#X obj 200 309 dac~; +#X obj 16 8 cnv 15 550 40 empty empty disarray~ 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 msg 14 181 getattributes; +#X obj 427 281 print A; +#X obj 211 84 adc~ 1; +#X text 14 164 list attributes; +#X obj 211 217 disarray~ 1300 0 20; +#X msg 369 120 freq \$1; +#X obj 296 87 bng 25 250 50 0 empty empty reshuffle 0 -6 0 8 -225271 +-1 -1; +#X obj 454 88 nbx 5 18 0 1000 0 0 empty empty shuffle_count 0 -6 0 +10 -225271 -1 -1 0 256; +#X msg 454 120 shcnt \$1; +#X text 292 199 knee frq \, quality \, shuffle count; +#X text 424 300 attributes; +#X connect 0 0 1 0; +#X connect 1 0 13 0; +#X connect 2 0 14 0; +#X connect 3 0 5 0; +#X connect 3 0 5 1; +#X connect 4 0 3 1; +#X connect 9 0 13 0; +#X connect 11 0 13 0; +#X connect 13 0 3 0; +#X connect 13 1 10 0; +#X connect 14 0 13 0; +#X connect 15 0 13 0; +#X connect 16 0 17 0; +#X connect 17 0 13 0; diff --git a/externals/grill/fftease/pd/ether.pd b/externals/grill/fftease/pd/ether.pd new file mode 100644 index 00000000..3448f300 --- /dev/null +++ b/externals/grill/fftease/pd/ether.pd @@ -0,0 +1,39 @@ +#N canvas 140 138 600 366 12; +#X obj 17 78 tgl 20 1 empty empty enable_dsp 0 -6 0 10 -225271 -1 -1 +1 1; +#X msg 17 103 enable \$1; +#X obj 211 272 *~; +#X obj 252 277 hsl 128 15 0.001 10 1 1 empty empty volume -2 -6 0 10 +-261681 -1 -1 7800 1; +#X obj 200 309 dac~; +#X obj 16 8 cnv 15 550 40 empty empty ether~ 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 msg 14 181 getattributes; +#X obj 427 281 print A; +#X text 14 164 list attributes; +#X obj 419 87 nbx 5 18 0 1000 0 0 empty empty index 0 -6 0 10 -225271 +-1 -1 56 256; +#X text 424 300 attributes; +#X msg 307 120 invert \$1; +#X obj 307 86 tgl 25 0 empty empty invert 0 -6 0 8 -225271 -1 -1 1 +1; +#X msg 419 119 index \$1; +#X obj 211 217 ether~ 1; +#X text 280 215 quality \, invert \, index; +#X obj 211 84 adc~; +#X connect 0 0 1 0; +#X connect 1 0 16 0; +#X connect 2 0 4 0; +#X connect 2 0 4 1; +#X connect 3 0 2 1; +#X connect 8 0 16 0; +#X connect 11 0 15 0; +#X connect 13 0 16 0; +#X connect 14 0 13 0; +#X connect 15 0 16 0; +#X connect 16 0 2 0; +#X connect 16 1 9 0; +#X connect 18 0 16 0; +#X connect 18 1 16 1; diff --git a/externals/grill/fftease/src/burrow~.cpp b/externals/grill/fftease/src/burrow~.cpp index f299ce3f..8398bbbb 100644 --- a/externals/grill/fftease/src/burrow~.cpp +++ b/externals/grill/fftease/src/burrow~.cpp @@ -30,8 +30,8 @@ protected: F _thresh_dB,_mult_dB; private: - 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))); } + 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); @@ -55,7 +55,7 @@ V burrow::setup(t_classid c) burrow::burrow(I argc,const t_atom *argv): - fftease(4,F_STEREO|F_WINDOW|F_BITSHUFFLE), + fftease(4,F_STEREO|F_BALANCED|F_BITSHUFFLE|F_CONVERT), _thresh_dB(-30),_mult_dB(-18), _invert(false) { @@ -90,31 +90,18 @@ burrow::burrow(I argc,const t_atom *argv): V burrow::Transform(I _N2,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 */ - register F a,b; - - a = ( i == _N2 ? _buffer1[1] : _buffer1[even] ); - b = ( i == 0 || i == _N2 ? 0. : _buffer1[odd] ); - - F amp1 = hypot( a, b ); - F phase1 = -atan2( b, a ); - - a = ( i == _N2 ? _buffer2[1] : _buffer2[even] ); - b = ( i == 0 || i == _N2 ? 0. : _buffer2[odd] ); - - F amp2 = hypot( a, b ); - - /* use simple threshold from second signal to trigger filtering */ - if (_invert?(amp2 < _threshold):(amp2 > _threshold) ) - amp1 *= _multiplier; - - /* convert back to complex form, read for the inverse fft */ - _buffer1[even] = amp1 * cos(phase1); - if ( i != _N2 ) _buffer1[odd] = -amp1 * sin(phase1); - } + 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!) + + if(_invert) + for (I i = 0; i <= _N; i += 2) + if(_channel2[i] < thr) _channel1[i] *= mul; + else + for (I i = 0; i <= _N; i += 2) + if(_channel2[i] > thr) _channel1[i] *= mul; } diff --git a/externals/grill/fftease/src/convert.c b/externals/grill/fftease/src/convert.c index 8eb238f0..07500f90 100644 --- a/externals/grill/fftease/src/convert.c +++ b/externals/grill/fftease/src/convert.c @@ -12,44 +12,49 @@ void convert(float *S, float *C, int N2, float *lastphase, float fundamental, float factor ) { - 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; - - 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]); - } - */ - } + float phase, phasediff; + int even,odd; + float a,b; + int i; + + for ( i = 0; i <= N2; i++ ) { + odd = ( even = i<<1 ) + 1; + a = ( i == N2 ? S[1] : S[even] ); + b = ( i == 0 || i == N2 ? 0. : S[odd] ); + + C[even] = hypot( a, b ); + if ( C[even] == 0. ) + phasediff = 0.; + else { + phasediff = ( phase = -atan2( b, a ) ) - lastphase[i]; + lastphase[i] = phase; + + while ( phasediff > PV_PI ) phasediff -= PV_2PI; + while ( phasediff < -PV_PI ) phasediff += PV_2PI; + } + + C[odd] = phasediff*factor + i*fundamental; + } +} + + +void unconvert(float *C, float *S, int N2, float *lastphase, float fundamental, float factor ) +{ + int i,even,odd; + float mag,phase; + + for ( i = 0; i <= N2; i++ ) { + odd = ( even = i<<1 ) + 1; + + mag = C[even]; + lastphase[i] += C[odd] - i*fundamental; + phase = lastphase[i]*factor; + + if(i != N2) { + S[even] = mag*cos( phase ); + S[odd] = -mag*sin( phase ); + } + else + S[1] = mag*cos( phase ); + } } diff --git a/externals/grill/fftease/src/convert_new.c b/externals/grill/fftease/src/convert_new.c deleted file mode 100644 index 5bf7e9a7..00000000 --- a/externals/grill/fftease/src/convert_new.c +++ /dev/null @@ -1,65 +0,0 @@ -/* T.Grill */ -#include "pv.h" - -/* #include */ -#include - - - -/* S is a spectrum in rfft format, i.e., it contains N real values - arranged as real followed by imaginary values, except for first - two values, which are real parts of 0 and Nyquist frequencies; - convert first changes these into N/2+1 PAIRS of magnitude and - phase values to be stored in output array C; the phases are then - unwrapped and successive phase differences are used to compute - estimates of the instantaneous frequencies for each phase vocoder - analysis channel; decimation rate D and sampling rate R are used - to render these frequency values directly in Hz. */ - - - - - -void convert_new(float *S, float *C, int N2, float *lastphase, float fundamental, float factor ) -{ - 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; - - 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]); - } - */ - } -} diff --git a/externals/grill/fftease/src/cross~.cpp b/externals/grill/fftease/src/cross~.cpp index 8fbc2c22..e794d761 100644 --- a/externals/grill/fftease/src/cross~.cpp +++ b/externals/grill/fftease/src/cross~.cpp @@ -18,18 +18,18 @@ class cross: FLEXT_HEADER(cross,fftease) public: - cross(I argc,const t_atom *argv); + cross(); protected: virtual V Transform(I _N2,S *const *in); }; -FLEXT_LIB_DSP_V("fftease, cross~",cross) +FLEXT_LIB_DSP("fftease, cross~",cross) -cross::cross(I argc,const t_atom *argv): - fftease(2,F_STEREO|F_WINDOW|F_BITSHUFFLE) +cross::cross(): + fftease(2,F_STEREO|F_BALANCED|F_BITSHUFFLE|F_CONVERT) { AddInSignal("Messages and driver signal"); AddInSignal("Filter signal"); @@ -39,30 +39,12 @@ cross::cross(I argc,const t_atom *argv): V cross::Transform(I _N2,S *const *in) { - // TG: filled only once per signal vector!! - const F threshie = *in[0]; - - for (I i = 0; i <= _N2; i++ ) { - const I even = i*2,odd = even+1; - - F a = ( i == _N2 ? _buffer1[1] : _buffer2[even] ); - F b = ( i == 0 || i == _N2 ? 0. : _buffer2[odd] ); - - F amp1 = hypot( a, b ) ; - - a = ( i == _N2 ? _buffer1[1] : _buffer1[even] ); - b = ( i == 0 || i == _N2 ? 0. : _buffer1[odd] ); - - F amp2 = hypot( a, b ); - F phase2 = -atan2( b, a ); + // filled only once per signal vector!! + register const F threshie = *in[0]; + const I _N = _N2*2; + for (I i = 0; i <= _N; i += 2) { // modulate amp2 with amp1 (if over threshold) - if( amp1 > threshie ) amp2 *= amp1; - - _buffer1[even] = amp2 * cos( phase2 ); - if ( i != _N2 ) _buffer1[odd] = -amp2 * sin( phase2 ); + 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 7c1206ee..14a08688 100644 --- a/externals/grill/fftease/src/dentist~.cpp +++ b/externals/grill/fftease/src/dentist~.cpp @@ -25,7 +25,7 @@ protected: virtual V Transform(I _N2,S *const *in); I *_bin_selection; - I _tooth_count; + I _teeth; F _knee; I _max_bin; // determined by _knee and fundamental frequency @@ -38,7 +38,7 @@ private: virtual V Delete(); V ms_knee(F knee); - V ms_teeth(I teeth) { _tooth_count = teeth; reset_shuffle(); } + V ms_teeth(I teeth) { _teeth = teeth; reset_shuffle(); } static V setup(t_classid c); @@ -46,7 +46,7 @@ private: FLEXT_CALLBACK(reset_shuffle) FLEXT_ATTRGET_F(_knee) FLEXT_CALLSET_F(ms_knee) - FLEXT_ATTRGET_I(_tooth_count) + FLEXT_ATTRGET_I(_teeth) FLEXT_CALLSET_I(ms_teeth) }; @@ -58,13 +58,13 @@ V dentist::setup(t_classid c) FLEXT_CADDBANG(c,0,reset_shuffle); FLEXT_CADDATTR_VAR(c,"knee",_knee,ms_knee); - FLEXT_CADDATTR_VAR(c,"teeth",_tooth_count,ms_teeth); + FLEXT_CADDATTR_VAR(c,"teeth",_teeth,ms_teeth); } dentist::dentist(I argc,const t_atom *argv): - fftease(4,F_WINDOW|F_BITSHUFFLE|F_CONVERT), - _knee(500),_tooth_count(10) + fftease(4,F_BALANCED|F_BITSHUFFLE|F_CONVERT), + _knee(500),_teeth(10) { /* parse and set object's options given */ if(argc >= 1) { @@ -75,9 +75,9 @@ dentist::dentist(I argc,const t_atom *argv): } if(argc >= 2) { if(CanbeInt(argv[1])) - _tooth_count = GetAInt(argv[1]); + _teeth = GetAInt(argv[1]); else - post("%s - Teeth must be an integer value - set to %0i",thisName(),_tooth_count); + post("%s - Teeth must be an integer value - set to %0i",thisName(),_teeth); } AddInSignal("Messages and input signal"); @@ -103,14 +103,15 @@ V dentist::ms_knee(F f) { _knee = f; // store original - const F funda = Samplerate()/(2*Mult()*Blocksize()); + const F funda = get_Fund(); // TG: This is a different, but steady correction than in original fftease if( f < funda ) f = funda; - else if(f > funda/2) f = funda/2; + else if(f > Samplerate()/2) f = Samplerate()/2; - _max_bin = 1; - for(F curfreq = 0; curfreq < f; curfreq += funda) ++_max_bin; + _max_bin = (I)(f/funda+0.5); + + reset_shuffle(); } @@ -118,11 +119,10 @@ V dentist::Set() { fftease::Set(); + _bin_selection = new I[get_N()/2]; + // calculation of _max_bin ms_knee(_knee); - - _bin_selection = new I[(Blocksize()*Mult())>>1]; - reset_shuffle(); } V dentist::Transform(I _N2,S *const *in) @@ -135,17 +135,17 @@ V dentist::Transform(I _N2,S *const *in) V dentist::reset_shuffle() { - const I _N2 = Blocksize()*Mult()/2; - I teeth = _tooth_count; + const I _N2 = get_N()/2; + I t = _teeth; // check number of teeth - if( teeth < 0 ) teeth = 0; - else if( teeth > _N2 ) teeth = _N2; + if( t < 0 ) t = 0; + else if( t > _N2 ) t = _N2; // clear and set random bins I i; for( i = 0; i < _N2; i++ ) _bin_selection[i] = 0; - for( i = 0; i < _tooth_count; i++ ) + for( i = 0; i < t; i++ ) _bin_selection[rand()%_max_bin] = 1; } diff --git a/externals/grill/fftease/src/disarray~.cpp b/externals/grill/fftease/src/disarray~.cpp index c45d6583..e297131d 100644 --- a/externals/grill/fftease/src/disarray~.cpp +++ b/externals/grill/fftease/src/disarray~.cpp @@ -24,13 +24,11 @@ protected: virtual V Transform(I _N2,S *const *in); - BL _qual; I _shuffle_count,_max_bin; F _freq; I *_shuffle_in,*_shuffle_out; - V reset_shuffle(); private: @@ -45,6 +43,7 @@ private: FLEXT_CALLBACK(reset_shuffle) FLEXT_ATTRGET_F(_freq) FLEXT_CALLSET_F(ms_freq) + FLEXT_ATTRVAR_I(_shuffle_count) }; FLEXT_LIB_DSP_V("fftease, disarray~",disarray) @@ -55,6 +54,7 @@ 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); } @@ -82,8 +82,8 @@ disarray::disarray(I argc,const t_atom *argv): post("%s - Shufflecount must be an integer value - set to %0i",thisName(),_shuffle_count); } - _mult = _qual?4:2; - if(_qual) _flags |= F_WINDOW; + Mult(_qual?4:2); + if(_qual) _flags |= F_BALANCED; AddInSignal("Messages and input signal"); AddOutSignal("Transformed signal"); @@ -107,29 +107,28 @@ V disarray::Set() { fftease::Set(); - const I _N2 = Blocksize()*Mult()/2; + const I _N2 = get_N()/2; _shuffle_in = new I[_N2]; _shuffle_out = new I[_N2]; // calculate _max_bin ms_freq(_freq); - - reset_shuffle(); } V disarray::ms_freq(F f) { _freq = f; // store original - const F funda = Samplerate()/(2*Mult()*Blocksize()); + const F funda = get_Fund(); // TG: This is a different, but steady correction than in original fftease if( f < funda ) f = funda; - else if(f > funda/2) f = funda/2; + else if(f > Samplerate()/2) f = Samplerate()/2; - _max_bin = 1; - for(F curfreq = 0; curfreq < f; curfreq += funda) ++_max_bin; + _max_bin = (I)(f/funda+0.5); + + reset_shuffle(); } inline V swap(F &a,F &b) { F t = a; a = b; b = t; } @@ -137,14 +136,18 @@ inline V swap(I &a,I &b) { I t = a; a = b; b = t; } V disarray::Transform(I _N2,S *const *in) { - for(I i = 0; i < _shuffle_count ; i++) + I shcnt = _shuffle_count; + if(shcnt < 0) shcnt = 0; + else if(shcnt > _N2) shcnt = _N2; + + for(I i = 0; i < shcnt; i++) swap(_channel1[ _shuffle_in[i] * 2 ],_channel1[ _shuffle_out[i] * 2]); } V disarray::reset_shuffle() { - const I _N2 = Blocksize()*Mult()/2; + const I _N2 = get_N()/2; I i; for( i = 0; i < _N2; i++ ) diff --git a/externals/grill/fftease/src/drown~.cpp b/externals/grill/fftease/src/drown~.cpp index 2d6b46ba..171fbaf8 100644 --- a/externals/grill/fftease/src/drown~.cpp +++ b/externals/grill/fftease/src/drown~.cpp @@ -24,11 +24,11 @@ protected: virtual V Transform(I n,S *const *in); }; -FLEXT_LIB_DSP_V("fftease, drown~",drown) +FLEXT_LIB_DSP_V("fftease, drown~ denude~",drown) drown::drown(I argc,const t_atom *argv): - fftease(4,F_WINDOW) + fftease(4,F_BALANCED|F_CONVERT) { AddInSignal("Messages and input signal"); AddInSignal("Threshold generator signal"); @@ -40,29 +40,13 @@ drown::drown(I argc,const t_atom *argv): V drown::Transform(I _N2,S *const *in) { // only first value of the signal vectors - const F thresh = in[0][0],mult = in[1][0]; + const F thresh = *in[0],mult = *in[1]; - // nudist helper function is integrated + const I _N = _N2*2; - for (I i = 0; i <= _N2; i++ ) { - const I real = i*2,imag = real+1; - F amp,phase; - - // convert to amp and phase - const F a = ( i == _N2 ? _buffer1[1] : _buffer1[real] ); - const F b = ( i == 0 || i == _N2 ? 0. : _buffer1[imag] ); - - amp = hypot( a, b ); - // make up low amplitude bins - if(amp < thresh) amp *= mult; - - phase = -atan2( b, a ); - - - // convert back to real and imag - _buffer1[real] = amp * cos( phase ); - if (i != _N2) _buffer1[imag] = -amp * sin( phase ); - } + // 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 836349f3..f75a6632 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), + fftease(2,F_STEREO|F_BITSHUFFLE|F_CONVERT), _qual(false),_threshMult(0),_invert(false) { /* parse and set object's options given */ @@ -57,8 +57,8 @@ ether::ether(I argc,const t_atom *argv): post("%s - Quality must be a boolean value - set to %0i",thisName(),_qual?1:0); } - _mult = _qual?4:2; - if(_qual) _flags |= F_WINDOW; + Mult(_qual?4:2); + if(_qual) _flags |= F_BALANCED; AddInSignal("Messages and input signal"); AddInSignal("Reference signal"); @@ -68,36 +68,21 @@ ether::ether(I argc,const t_atom *argv): V ether::Transform(I _N2,S *const *in) { - F threshMult = _threshMult; - if (threshMult == 0. ) threshMult = 1; + const I _N = _N2*2; + const BL inv = _invert; + const F threshMult = _threshMult?_threshMult:1; - for (I i = 0; i <= _N2; i++ ) { - const I even = i*2,odd = even + 1; + for (I i = 0; i <= _N; i += 2) { + F &1 = _channel1[i]; + F &phase1 = _channel1[i+1]; - // convert to polar coordinates from complex values - register F a,b; - - a = ( i == _N2 ? _buffer1[1] : _buffer1[even] ); - b = ( i == 0 || i == _N2 ? 0. : _buffer1[odd] ); - - F amp1 = hypot( a, b ); - F phase1 = -atan2( b, a ); - - a = ( i == _N2 ? _buffer2[1] : _buffer2[even] ); - b = ( i == 0 || i == _N2 ? 0. : _buffer2[odd] ); - - F amp2 = hypot( a, b ); - F phase2 = -atan2( b, a ); + F &2 = _channel2[i]; + F &phase2 = _channel2[i+1]; // use simple threshold for inverse compositing - if(_invert?(amp1 > amp2*threshMult):(amp1 < amp2*threshMult) ) amp1 = amp2; + if(inv?(amp1 > amp2*threshMult):(amp1 < amp2*threshMult) ) amp1 = amp2; if (phase1 == 0. ) phase1 = phase2; - - - // convert back to complex form, read for the inverse fft - _buffer1[even] = amp1 * cos(phase1); - if(i != _N2) _buffer1[odd] = -amp1 * sin(phase1); } } diff --git a/externals/grill/fftease/src/fft.c b/externals/grill/fftease/src/fft.c index 11c5da6d..4cd31199 100644 --- a/externals/grill/fftease/src/fft.c +++ b/externals/grill/fftease/src/fft.c @@ -1,8 +1,6 @@ #include "pv.h" -/* float TWOPI; */ - /* If forward is true, rfft replaces 2*N real data points in x with N complex values representing the positive frequency half of their Fourier spectrum, with x[1] replaced with the real part of the Nyquist @@ -12,6 +10,8 @@ static void bitreverse( float *x, int N ); +static float sqr(float x) { return x*x; } + void rfft( float *x, int N, int forward ) { float c1,c2, @@ -26,15 +26,12 @@ void rfft( float *x, int N, int forward ) i1,i2,i3,i4, N2p1; static int first = 1; -float PI, TWOPI; -PI = 3.141592653589793115997963468544185161590576171875; -TWOPI = 6.28318530717958623199592693708837032318115234375; - if ( first ) { + if ( first ) { first = 0; } - theta = PI/N; + theta = PV_PI/N; wr = 1.; wi = 0.; c1 = 0.5; @@ -50,7 +47,7 @@ TWOPI = 6.28318530717958623199592693708837032318115234375; xi = 0.; x[1] = 0.; } - wpr = -2.*pow( sin( 0.5*theta ), 2. ); + wpr = -2.*sqr( sin( 0.5*theta )); wpi = sin( theta ); N2p1 = (N<<1) + 1; for ( i = 0; i <= N>>1; i++ ) { @@ -104,14 +101,13 @@ void cfft( float *x, int NC, int forward ) m, i,j, delta; -float TWOPI; -TWOPI = 6.28318530717958623199592693708837032318115234375; - ND = NC<<1; + + ND = NC<<1; bitreverse( x, ND ); for ( mmax = 2; mmax < ND; mmax = delta ) { delta = mmax<<1; - theta = TWOPI/( forward? mmax : -mmax ); - wpr = -2.*pow( sin( 0.5*theta ), 2. ); + theta = PV_2PI/( forward? mmax : -mmax ); + wpr = -2.*sqr( sin( 0.5*theta )); wpi = sin( theta ); wr = 1.; wi = 0.; diff --git a/externals/grill/fftease/src/fftease.cpp b/externals/grill/fftease/src/fftease.cpp index 4944e839..f67ed28f 100644 --- a/externals/grill/fftease/src/fftease.cpp +++ b/externals/grill/fftease/src/fftease.cpp @@ -13,7 +13,7 @@ WARRANTIES, see the file, "license.txt," in this distribution. fftease::fftease(I mult,I flags): - _mult(mult),_flags(flags), + _mult(mult),_flags(flags),_N(0), _inCount(0), blsz(0),smprt(0) {} @@ -38,6 +38,7 @@ V fftease::m_dsp(I n,S *const *in,S *const *out) if(_D != blsz || sr != smprt) { blsz = _D; smprt = sr; + MakeVar(); Delete(); Set(); @@ -48,7 +49,7 @@ V fftease::m_signal(I n,S *const *in,S *const *out) { /* declare working variables */ I i; - const I _D = n,_N = _D*Mult(),_Nw = _N,_N2 = _N/2,_Nw2 = _Nw/2; + const I _D = n,_N = get_N(),_Nw = _N,_N2 = _N/2,_Nw2 = _Nw/2; /* fill our retaining buffers */ _inCount += _D; @@ -132,7 +133,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; @@ -156,7 +157,7 @@ void fftease::Set() _Hwin = new F[_Nw]; _Wanal = new F[_Nw]; _Wsyn = new F[_Nw]; - if(_flags&F_WINDOW) + if(_flags&F_BALANCED) makewindows( _Hwin, _Wanal, _Wsyn, _Nw, _N, _D, 0); else makehanning( _Hwin, _Wanal, _Wsyn, _Nw, _N, _D, 0,0); diff --git a/externals/grill/fftease/src/fold.c b/externals/grill/fftease/src/fold.c index 0ecee5d6..2c380032 100644 --- a/externals/grill/fftease/src/fold.c +++ b/externals/grill/fftease/src/fold.c @@ -6,19 +6,33 @@ */ void fold( float *I, float *W, int Nw, float *O, int N, int n ) { - int i; + for ( i = 0; i < N; i++ ) O[i] = 0.; - for ( i = 0; i < N; i++ ) - O[i] = 0.; - - while ( n < 0 ) - n += N; + while ( n < 0 ) n += N; n %= N; + for ( i = 0; i < Nw; i++ ) { - O[n] += I[i]*W[i]; - if ( ++n == N ) - n = 0; + O[n] += I[i]*W[i]; + if ( ++n == N ) n = 0; + } +} + + +/* + * input I is a folded spectrum of length N; output O and + * synthesis window W are of length Nw--overlap-add windowed, + * unrotated, unfolded input data into output O + */ +void overlapadd( float *I, int N, float *W, float *O, int Nw, int n ) +{ + 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 ; } } diff --git a/externals/grill/fftease/src/leanconvert.c b/externals/grill/fftease/src/leanconvert.c index 36b1452a..ecb6bc54 100644 --- a/externals/grill/fftease/src/leanconvert.c +++ b/externals/grill/fftease/src/leanconvert.c @@ -2,18 +2,42 @@ void leanconvert( float *S, float *C, int N2 ) { + register int i; - 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 ); - } + float a = S[0]; // real value at f=0 + float b = S[1]; // real value at f=Nyquist + + C[0] = fabs(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] ); + } + + C[0] = fabs(b); + C[1] = 0; +} + + +/* unconvert essentially undoes what convert does, i.e., it + turns N2+1 PAIRS of amplitude and frequency values in + C into N2 PAIR of complex spectrum data (in rfft format) + in output array S; sampling rate R and interpolation factor + I are used to recompute phase values from frequencies */ + +void leanunconvert( float *C, float *S, int N2 ) +{ + register int i; + + S[0] = fabs(C[0]); + S[1] = fabs(C[N2*2]); + S += 2,C += 2; + + for (i = 1; i < N2; i++,S += 2,C += 2 ) { + S[0] = C[0] * cos( C[1] ); + S[1] = -C[0] * sin( C[1] ); + } } diff --git a/externals/grill/fftease/src/leanunconvert.c b/externals/grill/fftease/src/leanunconvert.c deleted file mode 100644 index f8575168..00000000 --- a/externals/grill/fftease/src/leanunconvert.c +++ /dev/null @@ -1,23 +0,0 @@ -#include "pv.h" - -/* unconvert essentially undoes what convert does, i.e., it - turns N2+1 PAIRS of amplitude and frequency values in - C into N2 PAIR of complex spectrum data (in rfft format) - in output array S; sampling rate R and interpolation factor - I are used to recompute phase values from frequencies */ - -void leanunconvert( float *C, float *S, int N2 ) -{ - 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) ); - } -} - diff --git a/externals/grill/fftease/src/main.h b/externals/grill/fftease/src/main.h index aeaea3e4..0ee99584 100644 --- a/externals/grill/fftease/src/main.h +++ b/externals/grill/fftease/src/main.h @@ -47,6 +47,11 @@ public: fftease(I mult,I flags); virtual ~fftease(); + 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); } + protected: virtual BL Init(); @@ -61,7 +66,8 @@ protected: virtual V Transform(I _N2,S *const *in) = 0; - I Mult() const { return _mult; } + V Mult(I n) { _mult = n; MakeVar(); } + inline I Mult() const { return _mult; } F *_input1,*_input2; F *_buffer1,*_buffer2; @@ -75,18 +81,22 @@ protected: enum { F_STEREO = 0x01, - F_WINDOW = 0x02, + F_BALANCED = 0x02, F_BITSHUFFLE = 0x04, F_CONVERT = 0x08,F_CRES = 0x10, F_RMS = 0x20 }; - I _mult,_flags; + I _flags; F _rms; private: + + V MakeVar() { _N = Blocksize()*_mult; } + I blsz; F smprt; + I _mult,_N; static V setup(t_classid c) {} diff --git a/externals/grill/fftease/src/makewindows.c b/externals/grill/fftease/src/makewindows.c index 1287390e..e26690ec 100644 --- a/externals/grill/fftease/src/makewindows.c +++ b/externals/grill/fftease/src/makewindows.c @@ -11,16 +11,12 @@ void makewindows( float *H, float *A, float *S, int Nw, int N, int I, int osc ) { int i ; float sum ; -float PI, TWOPI; - -PI = 3.141592653589793115997963468544185161590576171875; -TWOPI = 6.28318530717958623199592693708837032318115234375; /* * basic Hamming windows */ for ( i = 0 ; i < Nw ; i++ ) - H[i] = A[i] = S[i] = 0.54 - 0.46*cos( TWOPI*i/(Nw - 1) ) ; + H[i] = A[i] = S[i] = 0.54 - 0.46*cos( PV_2PI*i/(Nw - 1) ) ; /* * when Nw > N, also apply interpolating (sinc) windows to * ensure that window are 0 at increments of N (the FFT length) @@ -36,9 +32,9 @@ TWOPI = 6.28318530717958623199592693708837032318115234375; x = -(Nw - 1)/2. ; for ( i = 0 ; i < Nw ; i++, x += 1. ) if ( x != 0. ) { - A[i] *= N*sin( PI*x/N )/(PI*x) ; + A[i] *= N*sin( PV_PI*x/N )/(PV_PI*x) ; if ( I ) - S[i] *= I*sin( PI*x/I )/(PI*x) ; + S[i] *= I*sin( PV_PI*x/I )/(PV_PI*x) ; } } /* @@ -67,10 +63,6 @@ void makehamming( float *H, float *A, float *S, int Nw, int N, int I, int osc,in { int i; float sum ; -float PI, TWOPI; - -PI = 3.141592653589793115997963468544185161590576171875; -TWOPI = 6.28318530717958623199592693708837032318115234375; /* * basic Hamming windows @@ -79,13 +71,13 @@ TWOPI = 6.28318530717958623199592693708837032318115234375; if (odd) { for ( i = 0 ; i < Nw ; i++ ) - H[i] = A[i] = S[i] = sqrt(0.54 - 0.46*cos( TWOPI*i/(Nw - 1) )); + H[i] = A[i] = S[i] = sqrt(0.54 - 0.46*cos( PV_2PI*i/(Nw - 1) )); } else { for ( i = 0 ; i < Nw ; i++ ) - H[i] = A[i] = S[i] = 0.54 - 0.46*cos( TWOPI*i/(Nw - 1) ); + H[i] = A[i] = S[i] = 0.54 - 0.46*cos( PV_2PI*i/(Nw - 1) ); } @@ -104,9 +96,9 @@ TWOPI = 6.28318530717958623199592693708837032318115234375; x = -(Nw - 1)/2. ; for ( i = 0 ; i < Nw ; i++, x += 1. ) if ( x != 0. ) { - A[i] *= N*sin( PI*x/N )/(PI*x) ; + A[i] *= N*sin( PV_PI*x/N )/(PV_PI*x) ; if ( I ) - S[i] *= I*sin( PI*x/I )/(PI*x) ; + S[i] *= I*sin( PV_PI*x/I )/(PV_PI*x) ; } } /* @@ -136,10 +128,6 @@ void makehanning( float *H, float *A, float *S, int Nw, int N, int I, int osc, i { int i; float sum ; -float PI, TWOPI; - -PI = 3.141592653589793115997963468544185161590576171875; -TWOPI = 6.28318530717958623199592693708837032318115234375; /* * basic Hanning windows @@ -148,13 +136,13 @@ TWOPI = 6.28318530717958623199592693708837032318115234375; if (odd) { for ( i = 0 ; i < Nw ; i++ ) - H[i] = A[i] = S[i] = sqrt(0.5 * (1. + cos(PI + TWOPI * i / (Nw - 1)))); + H[i] = A[i] = S[i] = sqrt(0.5 * (1. + cos(PV_PI + PV_2PI * i / (Nw - 1)))); } else { for ( i = 0 ; i < Nw ; i++ ) - H[i] = A[i] = S[i] = 0.5 * (1. + cos(PI + TWOPI * i / (Nw - 1))); + H[i] = A[i] = S[i] = 0.5 * (1. + cos(PV_PI + PV_2PI * i / (Nw - 1))); } @@ -173,9 +161,9 @@ TWOPI = 6.28318530717958623199592693708837032318115234375; x = -(Nw - 1)/2. ; for ( i = 0 ; i < Nw ; i++, x += 1. ) if ( x != 0. ) { - A[i] *= N*sin( PI*x/N )/(PI*x) ; + A[i] *= N*sin( PV_PI*x/N )/(PV_PI*x) ; if ( I ) - S[i] *= I*sin( PI*x/I )/(PI*x) ; + S[i] *= I*sin( PV_PI*x/I )/(PV_PI*x) ; } } /* diff --git a/externals/grill/fftease/src/morphine~.cpp b/externals/grill/fftease/src/morphine~.cpp index 1febe853..14ba0971 100644 --- a/externals/grill/fftease/src/morphine~.cpp +++ b/externals/grill/fftease/src/morphine~.cpp @@ -51,7 +51,7 @@ V morphine::setup(t_classid c) morphine::morphine(I argc,const t_atom *argv): - fftease(4,F_STEREO|F_WINDOW|F_BITSHUFFLE|F_CONVERT), + fftease(4,F_STEREO|F_BALANCED|F_BITSHUFFLE|F_CONVERT), _index(1) { /* parse and set object's options given */ @@ -83,8 +83,7 @@ V morphine::Set() { fftease::Set(); - const I _N2 = Blocksize()*Mult()/2; - _picks = new pickme[_N2+1]; + _picks = new pickme[get_N()/2+1]; } I morphine::sortpicks( const void *a, const void *b ) @@ -106,12 +105,12 @@ V morphine::Transform(I _N2,S *const *in) // sort our differences in ascending order qsort( _picks, _N2+1, sizeof(pickme), sortpicks ); - const I morphindex = _index*(_N2+1)+.5; + const I morphindex2 = (I)(_index*(_N2+1)+.5)*2; + // choose the bins that are least different first - for ( i=0; i <= morphindex; i++ ) { - const I even = _picks[i].bin*2,odd = even + 1; - _channel1[even] = _channel2[even]; - _channel1[odd] = _channel2[odd]; + for (i=0; i <= morphindex2; i += 2) { + _channel1[i] = _channel2[i]; + _channel1[i+1] = _channel2[i+1]; } } diff --git a/externals/grill/fftease/src/overlapadd.c b/externals/grill/fftease/src/overlapadd.c deleted file mode 100644 index 7e832a00..00000000 --- a/externals/grill/fftease/src/overlapadd.c +++ /dev/null @@ -1,17 +0,0 @@ -/* - * input I is a folded spectrum of length N; output O and - * synthesis window W are of length Nw--overlap-add windowed, - * unrotated, unfolded input data into output O - */ -void overlapadd( float *I, int N, float *W, float *O, int Nw, int n ) -{ - 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 ; - } -} diff --git a/externals/grill/fftease/src/pv.h b/externals/grill/fftease/src/pv.h index 32f94543..0927c17c 100644 --- a/externals/grill/fftease/src/pv.h +++ b/externals/grill/fftease/src/pv.h @@ -25,6 +25,10 @@ extern "C" { #endif + +#define PV_PI 3.141592653589793115997963468544185161590576171875 +#define PV_2PI (2.*PV_PI) + /* ------------------------------------- */ diff --git a/externals/grill/fftease/src/scrape~.cpp b/externals/grill/fftease/src/scrape~.cpp index 9aa0245f..e31374bd 100644 --- a/externals/grill/fftease/src/scrape~.cpp +++ b/externals/grill/fftease/src/scrape~.cpp @@ -57,7 +57,7 @@ V scrape::setup(t_classid c) scrape::scrape(I argc,const t_atom *argv): - fftease(4,F_WINDOW|F_BITSHUFFLE|F_CONVERT), + fftease(4,F_BALANCED|F_BITSHUFFLE|F_CONVERT), _thresh1(.0001),_thresh2(.09), _knee(1000),_cutoff(4000) @@ -70,8 +70,8 @@ scrape::scrape(I argc,const t_atom *argv): post("%s - Knee must be a float value - set to %f",thisName(),_knee); } if(argc >= 2) { - if(CanbeFloat(argv[0])) { - F c = GetAFloat(argv[0]); + if(CanbeFloat(argv[1])) { + F c = GetAFloat(argv[1]); if(c > 0) _cutoff = c; else post("%s - Cutoff must be > 0 - set to %f",thisName(),_cutoff); @@ -101,15 +101,14 @@ V scrape::Set() { fftease::Set(); - const I _N2 = Blocksize()*Mult()/2; - _threshfunc = new F[_N2]; + _threshfunc = new F[get_N()/2]; UpdThrFun(); } V scrape::UpdThrFun() { - const I _N = Blocksize()*Mult(),_N2 = _N/2; - const F funda = Samplerate()/(_N*2); + const I _N2 = get_N()/2; + const F funda = get_Fund(); F curfreq = funda; for(I i = 0; i < _N2; i++ ) { diff --git a/externals/grill/fftease/src/shapee~.cpp b/externals/grill/fftease/src/shapee~.cpp index e6c0f3f7..0af5aa93 100644 --- a/externals/grill/fftease/src/shapee~.cpp +++ b/externals/grill/fftease/src/shapee~.cpp @@ -42,10 +42,12 @@ shapee::shapee(I argc,const t_atom *argv): post("%s - Quality must be a boolean value - set to %0i",thisName(),_qual?1:0); } - if(_qual) - _mult = 4,_flags |= F_WINDOW; + if(_qual) { + Mult(4); + _flags |= F_BALANCED; + } else - _mult = 2; + Mult(2); AddInSignal("Messages and frequency reference signal"); AddInSignal("Amplitude reference signal"); diff --git a/externals/grill/fftease/src/swinger~.cpp b/externals/grill/fftease/src/swinger~.cpp index 39fbd9a1..b2ecba34 100644 --- a/externals/grill/fftease/src/swinger~.cpp +++ b/externals/grill/fftease/src/swinger~.cpp @@ -49,10 +49,12 @@ V swinger::Transform(I _N2,S *const *in) // 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 ); diff --git a/externals/grill/fftease/src/taint~.cpp b/externals/grill/fftease/src/taint~.cpp index 675ced1a..18b7c076 100644 --- a/externals/grill/fftease/src/taint~.cpp +++ b/externals/grill/fftease/src/taint~.cpp @@ -24,7 +24,7 @@ protected: virtual V Transform(I n,S *const *in); - V ms_thresh(F thr) { _threshold = (F)pow(10.,(_threshdB = thr)*.05); } + V ms_thresh(F thr) { _threshold = FromdB(_threshdB = thr); } F _threshold,_threshdB; BL _invert; @@ -48,7 +48,7 @@ V taint::setup(t_classid c) taint::taint(I argc,const t_atom *argv): - fftease(4,F_STEREO|F_WINDOW|F_BITSHUFFLE|F_CONVERT), + fftease(4,F_STEREO|F_BALANCED|F_BITSHUFFLE|F_CONVERT), _threshdB(-10),_invert(false) { /* parse and set object's options given */ @@ -76,22 +76,25 @@ taint::taint(I argc,const t_atom *argv): V taint::Transform(I _N2,S *const *in) { - for (I i = 0; i <= _N2; i++ ) { - const I even = i*2, odd = even + 1; - - const F magnitude = _channel2[even]; + const I _N = _N2*2; + register const F thr = _threshold; + + if(_invert) { + // use threshold for inverse filtering to avoid division by zero + for (I i = 0; i <= _N; i += 2) { + const F magnitude = _channel2[i]; - if(_invert) { - // use threshold for inverse filtering to avoid division by zero - if ( magnitude < _threshold ) - _channel1[even] = 0; + if ( magnitude < thr ) + _channel1[i] = 0; else - _channel1[even] /= magnitude; + _channel1[i] /= magnitude; } - else { - // simple multiplication of magnitudes - if (magnitude > _threshold) - _channel1[even] *= magnitude; + } + else { + // simple multiplication of magnitudes + for (I i = 0; i <= _N; i += 2) { + const F magnitude = _channel2[i]; + if (magnitude > thr) _channel1[i] *= magnitude; } } } diff --git a/externals/grill/fftease/src/thresher~.cpp b/externals/grill/fftease/src/thresher~.cpp index 6be2389b..241dad12 100644 --- a/externals/grill/fftease/src/thresher~.cpp +++ b/externals/grill/fftease/src/thresher~.cpp @@ -52,15 +52,15 @@ void thresher::Set() fftease::Set(); const F _R = Samplerate(); - const I _D = Blocksize(),_N = _D*Mult(),_Nw = _N,_N2 = _N/2,_Nw2 = _Nw/2; + const I _D = Blocksize(),_N = get_N(),_N2 = _N/2; _compositeFrame = new F[_N+2]; - _framesLeft = new I[_N+2]; + _framesLeft = new I[_N2+1]; _c_lastphase_in = new F[_N2+1]; _c_lastphase_out = new F[_N2+1]; _c_fundamental = _R/_N; - _c_factor_in = _R/(_D * 3.14159265358979*2); + _c_factor_in = _R/(_D * PV_2PI); _c_factor_out = 1./_c_factor_in; _firstFrame = true; @@ -88,7 +88,7 @@ void thresher::Delete() thresher::thresher(): - fftease(4,F_WINDOW|F_BITSHUFFLE|F_CRES) + fftease(4,F_BALANCED|F_BITSHUFFLE|F_CRES) { AddInSignal("Messages and input signal"); AddOutSignal("Transformed signal"); @@ -101,23 +101,24 @@ V thresher::Transform(I _N2,S *const *in) convert( _buffer1, _channel1, _N2, _c_lastphase_in, _c_fundamental, _c_factor_in ); + I *fr = _framesLeft; if( _firstFrame ) { - for (I i = 0; i < _N+2; i++ ){ + for (I i = 0; i <= _N; i += 2,++fr ){ _compositeFrame[i] = _channel1[i]; - _framesLeft[i] = _maxHoldFrames; + _compositeFrame[i+1] = _channel1[i+1]; + *fr = _maxHoldFrames; } _firstFrame = false; } else { - for(I i = 0; i < _N+2; i += 2 ){ - if( (fabs( _compositeFrame[i] - _channel1[i] ) > _moveThreshold) || (_framesLeft[i] <= 0) ) { + for(I i = 0; i <= _N; i += 2,++fr ){ + if( (fabs( _compositeFrame[i] - _channel1[i] ) > _moveThreshold) || (*fr <= 0) ) { _compositeFrame[i] = _channel1[i]; _compositeFrame[i+1] = _channel1[i+1]; - _framesLeft[i] = _maxHoldFrames; - } - else { - _framesLeft[i]--; + *fr = _maxHoldFrames; } + else + --*fr; } } diff --git a/externals/grill/fftease/src/unconvert.c b/externals/grill/fftease/src/unconvert.c deleted file mode 100644 index 54bb6ca1..00000000 --- a/externals/grill/fftease/src/unconvert.c +++ /dev/null @@ -1,36 +0,0 @@ -#include "pv.h" - - - -void unconvert(float *C, float *S, int N2, float *lastphase, float fundamental, float factor ) -{ - 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); - } - */ - } - -} diff --git a/externals/grill/fftease/src/vacancy~.cpp b/externals/grill/fftease/src/vacancy~.cpp index a6d0a852..4377290d 100644 --- a/externals/grill/fftease/src/vacancy~.cpp +++ b/externals/grill/fftease/src/vacancy~.cpp @@ -23,7 +23,7 @@ public: protected: virtual V Transform(I n,S *const *in); - V ms_thresh(F thr) { _threshold = (F)pow(10.,(_threshdB = thr)*.05); } + V ms_thresh(F thr) { _threshold = FromdB(_threshdB = thr); } F _threshold,_threshdB; BL _invert,_useRms,_swapPhase; @@ -94,30 +94,31 @@ vacancy::vacancy(I argc,const t_atom *argv): V vacancy::Transform(I _N2,S *const *in) { const F useme = _useRms?_rms * _threshold:_threshold; + const I _N = _N2; // composite here please if (_invert) if (_swapPhase) - for (I i=0; i < _N2; i+=2 ) + 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 - for (I i=0; i < _N2; i+=2 ) + 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) - for (I i=0; i < _N2; i+=2 ) + 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 - for (I i=0; i < _N2; i+=2 ) + 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 fdb1e736..e509c827 100644 --- a/externals/grill/fftease/src/xsyn~.cpp +++ b/externals/grill/fftease/src/xsyn~.cpp @@ -30,7 +30,7 @@ FLEXT_LIB_DSP("fftease, xsyn~",xsyn) xsyn::xsyn(): fftease(2,F_STEREO|F_BITSHUFFLE|F_CONVERT) { - AddInSignal("Messages and Source signal 1"); + AddInSignal("Messages and source signal 1"); AddInSignal("Source signal 2"); AddOutSignal("Transformed signal"); } -- cgit v1.2.1