aboutsummaryrefslogtreecommitdiff
path: root/externals/grill/fftease
diff options
context:
space:
mode:
authorThomas Grill <xovo@users.sourceforge.net>2003-01-15 04:37:19 +0000
committerThomas Grill <xovo@users.sourceforge.net>2003-01-15 04:37:19 +0000
commitb00be027fe91e9ae5a19f53b6c1fd0245b4d4bae (patch)
tree2dd7ab22251e324b6d0f9167d3d32ed6e911a343 /externals/grill/fftease
parente62722bf0bba2ddb1b8558fa4c851c9e79dddf6c (diff)
""
svn path=/trunk/; revision=339
Diffstat (limited to 'externals/grill/fftease')
-rwxr-xr-xexternals/grill/fftease/fftease.cwbin131116 -> 203740 bytes
-rw-r--r--externals/grill/fftease/fftease.dsp4
-rw-r--r--externals/grill/fftease/make-files.txt2
-rw-r--r--externals/grill/fftease/src/burrow~.cpp150
-rw-r--r--externals/grill/fftease/src/cross~.cpp181
-rw-r--r--externals/grill/fftease/src/dentist~.cpp157
-rw-r--r--externals/grill/fftease/src/disarray~.cpp171
-rw-r--r--externals/grill/fftease/src/drown~.cpp168
-rw-r--r--externals/grill/fftease/src/ether~.cpp160
-rw-r--r--externals/grill/fftease/src/fftease.cpp185
-rw-r--r--externals/grill/fftease/src/main.h47
11 files changed, 314 insertions, 911 deletions
diff --git a/externals/grill/fftease/fftease.cw b/externals/grill/fftease/fftease.cw
index fb502752..8644858e 100755
--- a/externals/grill/fftease/fftease.cw
+++ b/externals/grill/fftease/fftease.cw
Binary files differ
diff --git a/externals/grill/fftease/fftease.dsp b/externals/grill/fftease/fftease.dsp
index 85b09613..f825d29b 100644
--- a/externals/grill/fftease/fftease.dsp
+++ b/externals/grill/fftease/fftease.dsp
@@ -409,6 +409,10 @@ SOURCE=".\ori.max\xsyn-opt~.c"
# End Group
# Begin Source File
+SOURCE=.\src\fftease.cpp
+# End Source File
+# Begin Source File
+
SOURCE=.\src\main.cpp
# End Source File
# Begin Source File
diff --git a/externals/grill/fftease/make-files.txt b/externals/grill/fftease/make-files.txt
index 567427b4..1866faa6 100644
--- a/externals/grill/fftease/make-files.txt
+++ b/externals/grill/fftease/make-files.txt
@@ -2,7 +2,7 @@
SRCS= \
convert.c convert_new.c fft4.c fft.c fold.c \
leanconvert.c leanunconvert.c makewindows.c overlapadd.c unconvert.c \
- main.cpp \
+ main.cpp fftease.cpp \
burrow~.cpp cross~.cpp dentist~.cpp disarray~.cpp drown~.cpp ether~.cpp
HDRS= \
diff --git a/externals/grill/fftease/src/burrow~.cpp b/externals/grill/fftease/src/burrow~.cpp
index d868cbb8..0bb3208f 100644
--- a/externals/grill/fftease/src/burrow~.cpp
+++ b/externals/grill/fftease/src/burrow~.cpp
@@ -13,41 +13,23 @@ WARRANTIES, see the file, "license.txt," in this distribution.
class burrow:
- public flext_dsp
+ public fftease
{
- FLEXT_HEADER_S(burrow,flext_dsp,setup)
+ FLEXT_HEADER_S(burrow,fftease,setup)
public:
burrow(I argc,const t_atom *argv);
- ~burrow();
protected:
- virtual V m_dsp(I n,S *const *in,S *const *out);
- virtual V m_signal(I n,S *const *in,S *const *out);
+ virtual V Transform(I _N2,S *const *in);
- I blsz;
BL _invert;
F _threshold,_multiplier;
F _thresh_dB,_mult_dB;
- F *_input1,*_input2;
- F *_buffer1,*_buffer2;
- F *_channel1,*_channel2;
- F *_output;
- F *_trigland;
- I *_bitshuffle;
- F *_Wanal,*_Wsyn,*_Hwin;
-
- I _inCount;
-
private:
- enum { _MULT_ = 4 };
-
- V Clear();
- V Delete();
-
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))); }
@@ -73,9 +55,9 @@ V burrow::setup(t_classid c)
burrow::burrow(I argc,const t_atom *argv):
+ fftease(4,true,true,true),
_thresh_dB(-30),_mult_dB(-18),
- _invert(false),
- blsz(0)
+ _invert(false)
{
/* parse and set object's options given */
if(argc >= 1) {
@@ -100,113 +82,15 @@ burrow::burrow(I argc,const t_atom *argv):
ms_thresh(_thresh_dB);
ms_mult(_mult_dB);
- Clear();
-
AddInSignal("Messages and input signal");
AddInSignal("Reference signal");
AddOutSignal("Transformed signal");
}
-burrow::~burrow()
-{
- Delete();
-}
-
-V burrow::Clear()
-{
- _bitshuffle = NULL;
- _trigland = NULL;
- _input1 = _input2 = NULL;
- _Hwin = NULL;
- _Wanal = _Wsyn = NULL;
- _buffer1 = _buffer2 = NULL;
- _channel1 = _channel2 = NULL;
- _output = NULL;
-}
-
-V burrow::Delete()
-{
- if(_bitshuffle) delete[] _bitshuffle;
- if(_trigland) delete[] _trigland;
- if(_input1) delete[] _input1;
- if(_input2) delete[] _input2;
- if(_Hwin) delete[] _Hwin;
- if(_Wanal) delete[] _Wanal;
- if(_Wsyn) delete[] _Wsyn;
- if(_buffer1) delete[] _buffer1;
- if(_buffer2) delete[] _buffer2;
- if(_channel1) delete[] _channel1;
- if(_channel2) delete[] _channel2;
- if(_output) delete[] _output;
-}
-
-
-
-V burrow::m_dsp(I n,S *const *,S *const *)
-{
- const I _D = n;
- if(_D != blsz) {
- blsz = _D;
-
- Delete();
-
- /* preset the objects data */
- const I _N = _D*_MULT_,_Nw = _N,_N2 = _N/2,_Nw2 = _Nw/2;
-
- _inCount = -_Nw;
-
- /* assign memory to the buffers */
- _input1 = new F[_Nw];
- _input2 = new F[_Nw];
- _buffer1 = new F[_N];
- _buffer2 = new F[_N];
- _channel1 = new F[_N+2];
- _channel2 = new F[_N+2];
- _output = new F[_Nw];
- _bitshuffle = new I[_N*2];
- _trigland = new F[_N*2];
-
- _Hwin = new F[_Nw];
- _Wanal = new F[_Nw];
- _Wsyn = new F[_Nw];
-
- /* initialize pv-lib functions */
- init_rdft( _N, _bitshuffle, _trigland);
- makewindows( _Hwin, _Wanal, _Wsyn, _Nw, _N, _D, 0);
- }
-}
-
-V burrow::m_signal(I n,S *const *in,S *const *out)
+V burrow::Transform(I _N2,S *const *in)
{
- /* declare working variables */
- I i, j;
- const I _D = n,_N = _D*_MULT_,_Nw = _N,_N2 = _N/2,_Nw2 = _Nw/2;
-
- /* fill our retaining buffers */
- _inCount += _D;
-
- for(i = 0; i < _N-_D ; i++ ) {
- _input1[i] = _input1[i+_D];
- _input2[i] = _input2[i+_D];
- }
- for(j = 0; i < _N; i++,j++) {
- _input1[i] = in[0][j];
- _input2[i] = in[1][j];
- }
-
- /* apply hamming window and fold our window buffer into the fft buffer */
- fold( _input1, _Wanal, _Nw, _buffer1, _N, _inCount );
- fold( _input2, _Wanal, _Nw, _buffer2, _N, _inCount );
-
- /* do an fft */
- rdft( _N, 1, _buffer1, _bitshuffle, _trigland );
- rdft( _N, 1, _buffer2, _bitshuffle, _trigland );
-
-
- // ---- BEGIN --------------------------------
-
- for ( i = 0; i <= _N2; i++ ) {
+ for (I i = 0; i <= _N2; i++ ) {
const I even = i<<1,odd = even+1;
/* convert to polar coordinates from complex values */
@@ -233,26 +117,6 @@ V burrow::m_signal(I n,S *const *in,S *const *out)
if ( i != _N2 )
_buffer1[odd] = -_channel1[even] * sin( _channel1[odd] );
}
-
-
- // ---- END --------------------------------
-
-
- /* do an inverse fft */
- rdft( _N, -1, _buffer1, _bitshuffle, _trigland );
-
- /* dewindow our result */
- overlapadd( _buffer1, _N, _Wsyn, _output, _Nw, _inCount);
-
- /* set our output and adjust our retaining output buffer */
- const F mult = 1./_N;
- for ( j = 0; j < _D; j++ )
- out[0][j] = _output[j] * mult;
-
- for ( j = 0; j < _N-_D; j++ )
- _output[j] = _output[j+_D];
- for (; j < _N; j++ )
- _output[j] = 0.;
}
diff --git a/externals/grill/fftease/src/cross~.cpp b/externals/grill/fftease/src/cross~.cpp
index 0eb19c02..728e868a 100644
--- a/externals/grill/fftease/src/cross~.cpp
+++ b/externals/grill/fftease/src/cross~.cpp
@@ -13,188 +13,36 @@ WARRANTIES, see the file, "license.txt," in this distribution.
class cross:
- public flext_dsp
+ public fftease
{
- FLEXT_HEADER_S(cross,flext_dsp,setup)
+ FLEXT_HEADER(cross,fftease)
public:
cross(I argc,const t_atom *argv);
- ~cross();
protected:
- virtual V m_dsp(I n,S *const *in,S *const *out);
- virtual V m_signal(I n,S *const *in,S *const *out);
-
- I blsz;
- F smprt;
-
- F *_input1,*_input2;
- F *_buffer1,*_buffer2;
- F *_channel1,*_channel2;
- F *_output;
- F *_trigland;
- I *_bitshuffle;
- F *_Wanal,*_Wsyn,*_Hwin;
-
- I _inCount;
-
-private:
- enum { _MULT_ = 2 };
-
- V Clear();
- V Delete();
-
- static V setup(t_classid c);
+ virtual V Transform(I _N2,S *const *in);
};
FLEXT_LIB_DSP_V("fftease, cross~",cross)
-V cross::setup(t_classid c)
-{
-}
-
-
cross::cross(I argc,const t_atom *argv):
- blsz(0),smprt(0)
+ fftease(2,true,true,true)
{
- Clear();
-
AddInSignal("Messages and driver signal");
AddInSignal("Filter signal");
AddInSignal("Threshold signal for cross synthesis");
AddOutSignal("Transformed signal");
}
-cross::~cross()
-{
- Delete();
-}
-
-V cross::Clear()
+V cross::Transform(I _N2,S *const *in)
{
- _input1 = _input2 = NULL;
- _buffer1 = _buffer2 = NULL;
- _channel1 = _channel2 = NULL;
- _output = NULL;
-
- _bitshuffle = NULL;
- _trigland = NULL;
-
- _Hwin = NULL;
- _Wanal = _Wsyn = NULL;
-}
-
-V cross::Delete()
-{
- if(_input1) delete[] _input1;
- if(_input2) delete[] _input2;
- if(_buffer1) delete[] _buffer1;
- if(_buffer2) delete[] _buffer2;
- if(_channel1) delete[] _channel1;
- if(_channel2) delete[] _channel2;
- if(_output) delete[] _output;
-
- if(_bitshuffle) delete[] _bitshuffle;
- if(_trigland) delete[] _trigland;
-
- if(_Wanal) delete[] _Wanal;
- if(_Wsyn) delete[] _Wsyn;
- if(_Hwin) delete[] _Hwin;
-
- // ---------------------------------------------
-
-#if 0
- // T.G. These are not used
- if(c_lastphase_in1) delete[] c_lastphase_in1;
- if(c_lastphase_in2) delete[] c_lastphase_in2;
- if(c_lastphase_out) delete[] c_lastphase_out;
-#endif
-}
-
-
-
-V cross::m_dsp(I n,S *const *,S *const *)
-{
- const I _D = n;
- const F _R = Samplerate();
-
- if(_D != blsz || _R != smprt) {
- blsz = _D;
- smprt = _R;
-
- Delete();
-
- const int _N = _D*_MULT_,_Nw = _N,_N2 = _N>>1,_Nw2 = _Nw>>1;
-
- _inCount = -_Nw;
-
- _input1 = new F[_Nw];
- _input2 = new F[_Nw];
- _buffer1 = new F[_N];
- _buffer2 = new F[_N];
- _channel1 = new F[_N+2];
- _channel2 = new F[_N+2];
- _output = new F[_Nw];
-
- _bitshuffle = new I[_N*2];
- _trigland = new F[_N*2];
-
- _Wanal = new F[_Nw];
- _Wsyn = new F[_Nw];
- _Hwin = new F[_Nw];
-
- init_rdft( _N, _bitshuffle, _trigland);
-
- // makewindows( x->Hwin, x->Wanal, x->Wsyn, x->Nw, x->N, x->D, 0);
- makehanning( _Hwin, _Wanal, _Wsyn, _Nw, _N, _D, 0,0);
-
- // ---------------------------------------------
-
-#if 0
- // T.G. These are not used
- /* for convert */
- c_lastphase_in1 = new F[_N2+1];
- c_lastphase_in2 = new F[_N2+1];
- c_lastphase_out = new F[_N2+1];
- c_fundamental = _R/( _N2<<1 );
- c_factor_in = _R/(_D * __TWOPI);
- c_factor_out = __TWOPI * _D/_R;
-#endif
- }
-}
-
-V cross::m_signal(I n,S *const *in,S *const *out)
-{
- /* declare working variables */
- I i, j;
- const I _D = n,_N = _D*_MULT_,_Nw = _N,_N2 = _N/2,_Nw2 = _Nw/2;
-
- _inCount += _D;
-
- for ( j = 0 ; j < _N-_D ; j++ ) {
- _input1[j] = _input1[j+_D];
- _input2[j] = _input2[j+_D];
- }
- for (i = 0; j < _N; j++,i++ ) {
- _input1[j] = in[0][i];
- _input2[j] = in[1][i];
- }
-
- fold( _input1, _Wanal, _Nw, _buffer1, _N, _inCount );
- fold( _input2, _Wanal, _Nw, _buffer2, _N, _inCount );
-
- rdft( _N, 1, _buffer1, _bitshuffle, _trigland );
- rdft( _N, 1, _buffer2, _bitshuffle, _trigland );
-
-
- // ---- BEGIN --------------------------------
-
// TG: filled only once per signal vector!!
- float threshie = *in[2];
+ float threshie = *in[0];
- for ( i = 0; i <= _N2; i++ ) {
+ for (I i = 0; i <= _N2; i++ ) {
const I even = i<<1,odd = even+1;
F a = ( i == _N2 ? _buffer1[1] : _buffer2[even] );
@@ -215,21 +63,6 @@ V cross::m_signal(I n,S *const *in,S *const *out)
if ( i != _N2 )
_buffer1[odd] = -_channel1[even] * sin( _channel1[odd] );
}
-
- // ---- END --------------------------------
-
- rdft( _N, -1, _buffer1, _bitshuffle, _trigland );
-
- overlapadd( _buffer1, _N, _Wsyn, _output, _Nw, _inCount);
-
- const F mult = 1./_N;
- for ( j = 0; j < _D; j++ )
- out[0][j] = _output[j] * mult;
-
- for ( j = 0; j < _N-_D; j++ )
- _output[j] = _output[j+_D];
- for (; j < _N; j++ )
- _output[j] = 0.;
}
diff --git a/externals/grill/fftease/src/dentist~.cpp b/externals/grill/fftease/src/dentist~.cpp
index 808796bd..375006b9 100644
--- a/externals/grill/fftease/src/dentist~.cpp
+++ b/externals/grill/fftease/src/dentist~.cpp
@@ -13,33 +13,16 @@ WARRANTIES, see the file, "license.txt," in this distribution.
#include <stdlib.h>
class dentist:
- public flext_dsp
+ public fftease
{
- FLEXT_HEADER_S(dentist,flext_dsp,setup)
+ FLEXT_HEADER_S(dentist,fftease,setup)
public:
dentist(I argc,const t_atom *argv);
- ~dentist();
protected:
- virtual V m_dsp(I n,S *const *in,S *const *out);
- virtual V m_signal(I n,S *const *in,S *const *out);
-
- I blsz;
- F smprt;
-
- F *_input1,*_input2;
- F *_buffer1,*_buffer2;
- F *_channel1,*_channel2;
- F *_output;
- F *_trigland;
- I *_bitshuffle;
- F *_Wanal,*_Wsyn,*_Hwin;
-
- I _inCount;
-
- // -----------------------------
+ virtual V Transform(I _N2,S *const *in);
I *_bin_selection;
I _tooth_count;
@@ -49,10 +32,10 @@ protected:
V reset_shuffle();
private:
- enum { _MULT_ = 4 };
- V Clear();
- V Delete();
+ virtual V Set();
+ virtual V Clear();
+ virtual V Delete();
V ms_knee(F knee);
V ms_teeth(I teeth) { _tooth_count = teeth; reset_shuffle(); }
@@ -80,7 +63,7 @@ V dentist::setup(t_classid c)
dentist::dentist(I argc,const t_atom *argv):
- blsz(0),smprt(0),
+ fftease(4,false,true,true),
_knee(500),_tooth_count(10)
{
/* parse and set object's options given */
@@ -97,55 +80,20 @@ dentist::dentist(I argc,const t_atom *argv):
post("%s - Teeth must be an integer value - set to %0i",thisName(),_tooth_count);
}
- Clear();
-
AddInSignal("Messages and input signal");
AddOutSignal("Transformed signal");
}
-dentist::~dentist()
-{
- Delete();
-}
-
V dentist::Clear()
{
- _input1 = _input2 = NULL;
- _buffer1 = _buffer2 = NULL;
- _channel1 = _channel2 = NULL;
- _output = NULL;
-
- _bitshuffle = NULL;
- _trigland = NULL;
-
- _Hwin = NULL;
- _Wanal = _Wsyn = NULL;
-
- // -----------------------------
+ fftease::Clear();
_bin_selection = NULL;
}
V dentist::Delete()
{
- if(_input1) delete[] _input1;
- if(_buffer1) delete[] _buffer1;
- if(_channel1) delete[] _channel1;
-/*
- if(_input2) delete[] _input2;
- if(_buffer2) delete[] _buffer2;
- if(_channel2) delete[] _channel2;
-*/
- if(_output) delete[] _output;
-
- if(_bitshuffle) delete[] _bitshuffle;
- if(_trigland) delete[] _trigland;
-
- if(_Wanal) delete[] _Wanal;
- if(_Wsyn) delete[] _Wsyn;
- if(_Hwin) delete[] _Hwin;
-
- // -----------------------------
+ fftease::Delete();
if(_bin_selection) delete[] _bin_selection;
}
@@ -155,7 +103,7 @@ V dentist::ms_knee(F f)
{
_knee = f; // store original
- const F funda = Samplerate()/(2*_MULT_*Blocksize());
+ const F funda = Samplerate()/(2*Mult()*Blocksize());
// TG: This is a different, but steady correction than in original fftease
if( f < funda ) f = funda;
@@ -166,97 +114,32 @@ V dentist::ms_knee(F f)
}
-V dentist::m_dsp(I n,S *const *,S *const *)
+V dentist::Set()
{
- const I _D = n;
- const F _R = Samplerate();
- if(_D != blsz || _R != smprt) {
- blsz = _D;
- smprt = _R;
-
- Delete();
- // ---------------------------------------------
-
- const int _N = _D*_MULT_,_Nw = _N,_Nw2 = _Nw>>1,_N2 = _N>>1;
-
- _inCount = -_Nw;
-
- _input1 = new F[_Nw];
- _buffer1 = new F[_N];
- _channel1 = new F[_N+2];
- /*
- _input2 = new F[_Nw];
- _buffer2 = new F[_N];
- _channel2 = new F[_N+2];
- */
-
- _output = new F[_Nw];
-
- _bitshuffle = new I[_N*2];
- _trigland = new F[_N*2];
-
- _Wanal = new F[_Nw];
- _Wsyn = new F[_Nw];
- _Hwin = new F[_Nw];
-
- init_rdft( _N, _bitshuffle, _trigland);
- makewindows( _Hwin, _Wanal, _Wsyn, _Nw, _N, _D, 0);
-
- // ---------------------------------------------
-
- // calculation of _max_bin
- ms_knee(_knee);
+ fftease::Set();
+
+ // calculation of _max_bin
+ ms_knee(_knee);
- _bin_selection = new I[_N2];
- reset_shuffle();
- }
+ _bin_selection = new I[(Blocksize()*Mult())>>1];
+ reset_shuffle();
}
-V dentist::m_signal(I n,S *const *in,S *const *out)
+V dentist::Transform(I _N2,S *const *in)
{
- /* declare working variables */
- I i, j;
- const I _D = n,_N = _D*_MULT_,_Nw = _N,_N2 = _N/2,_Nw2 = _Nw/2;
-
- _inCount += _D;
-
- for ( j = 0 ; j < _N-_D ; j++ )
- _input1[j] = _input1[j+_D];
- for (i = 0; j < _N; j++,i++ )
- _input1[j] = in[0][i];
-
- fold( _input1, _Wanal, _Nw, _buffer1, _N, _inCount );
- rdft( _N, 1, _buffer1, _bitshuffle, _trigland );
-
- // ---- BEGIN --------------------------------
-
leanconvert( _buffer1, _channel1, _N2 );
- for( i = 0; i < _N2 ; i++){
+ for(I i = 0; i < _N2 ; i++){
if( !_bin_selection[i] ) _channel1[i*2] = 0;
}
leanunconvert( _channel1, _buffer1, _N2 );
-
- // ---- END --------------------------------
-
- rdft( _N, -1, _buffer1, _bitshuffle, _trigland );
- overlapadd( _buffer1, _N, _Wsyn, _output, _Nw, _inCount);
-
- const F mult = 1./_N;
- for ( j = 0; j < _D; j++ )
- out[0][j] = _output[j] * mult;
-
- for ( j = 0; j < _N-_D; j++ )
- _output[j] = _output[j+_D];
- for (; j < _N; j++ )
- _output[j] = 0.;
}
V dentist::reset_shuffle()
{
- const I _N2 = Blocksize()*_MULT_/2;
+ const I _N2 = Blocksize()*Mult()/2;
I teeth = _tooth_count;
// check number of teeth
diff --git a/externals/grill/fftease/src/disarray~.cpp b/externals/grill/fftease/src/disarray~.cpp
index 7ddc4333..8019fcdc 100644
--- a/externals/grill/fftease/src/disarray~.cpp
+++ b/externals/grill/fftease/src/disarray~.cpp
@@ -13,29 +13,16 @@ WARRANTIES, see the file, "license.txt," in this distribution.
#include <stdlib.h>
class disarray:
- public flext_dsp
+ public fftease
{
- FLEXT_HEADER_S(disarray,flext_dsp,setup)
+ FLEXT_HEADER_S(disarray,fftease,setup)
public:
disarray(I argc,const t_atom *argv);
- ~disarray();
protected:
- virtual V m_dsp(I n,S *const *in,S *const *out);
- virtual V m_signal(I n,S *const *in,S *const *out);
-
- I blsz;
- F smprt;
-
- F *_input1,*_input2;
- F *_buffer1,*_buffer2;
- F *_channel1,*_channel2;
- F *_output;
- F *_trigland;
- I *_bitshuffle;
- F *_Wanal,*_Wsyn,*_Hwin;
+ virtual V Transform(I _N2,S *const *in);
I _inCount,_nmult;
@@ -50,8 +37,9 @@ protected:
V reset_shuffle();
private:
- V Clear();
- V Delete();
+ virtual V Set();
+ virtual V Clear();
+ virtual V Delete();
V ms_freq(F f);
@@ -74,7 +62,7 @@ V disarray::setup(t_classid c)
disarray::disarray(I argc,const t_atom *argv):
- blsz(0),smprt(0),
+ fftease(2,false,true,true),
_freq(1300),_qual(false),_shuffle_count(20)
{
/* parse and set object's options given */
@@ -97,62 +85,41 @@ disarray::disarray(I argc,const t_atom *argv):
post("%s - Shufflecount must be an integer value - set to %0i",thisName(),_shuffle_count);
}
- _nmult = _qual?4:2;
-
- Clear();
+ _mult = _qual?4:2;
+ _window = _qual;
AddInSignal("Messages and input signal");
AddOutSignal("Transformed signal");
}
-disarray::~disarray()
-{
- Delete();
-}
V disarray::Clear()
{
- _input1 = _input2 = NULL;
- _buffer1 = _buffer2 = NULL;
- _channel1 = _channel2 = NULL;
- _output = NULL;
-
- _bitshuffle = NULL;
- _trigland = NULL;
-
- _Hwin = NULL;
- _Wanal = _Wsyn = NULL;
-
- // -----------------------------
-
+ fftease::Clear();
_shuffle_in = _shuffle_out = NULL;
}
V disarray::Delete()
{
- if(_input1) delete[] _input1;
- if(_buffer1) delete[] _buffer1;
- if(_channel1) delete[] _channel1;
-/*
- if(_input2) delete[] _input2;
- if(_buffer2) delete[] _buffer2;
- if(_channel2) delete[] _channel2;
-*/
- if(_output) delete[] _output;
+ fftease::Delete();
+ if(_shuffle_in) delete[] _shuffle_in;
+ if(_shuffle_out) delete[] _shuffle_out;
+}
- if(_bitshuffle) delete[] _bitshuffle;
- if(_trigland) delete[] _trigland;
+V disarray::Set()
+{
+ fftease::Set();
- if(_Wanal) delete[] _Wanal;
- if(_Wsyn) delete[] _Wsyn;
- if(_Hwin) delete[] _Hwin;
+ const I _N2 = Blocksize()*Mult()/2;
- // -----------------------------
+ _shuffle_in = new I[_N2];
+ _shuffle_out = new I[_N2];
- if(_shuffle_in) delete[] _shuffle_in;
- if(_shuffle_out) delete[] _shuffle_out;
-}
+ // calculate _max_bin
+ ms_freq(_freq);
+ reset_shuffle();
+}
V disarray::ms_freq(F f)
{
@@ -168,107 +135,23 @@ V disarray::ms_freq(F f)
for(F curfreq = 0; curfreq < f; curfreq += funda) ++_max_bin;
}
-
-V disarray::m_dsp(I n,S *const *,S *const *)
-{
- const I _D = n;
- const F _R = Samplerate();
-
- if(_D != blsz || _R != smprt) {
- blsz = _D;
- smprt = _R;
-
- Delete();
- // ---------------------------------------------
-
- const int _N = _D*_nmult,_Nw = _N,_Nw2 = _Nw>>1,_N2 = _N>>1;
-
- _inCount = -_Nw;
-
- _input1 = new F[_Nw];
- _buffer1 = new F[_N];
- _channel1 = new F[_N+2];
- /*
- _input2 = new F[_Nw];
- _buffer2 = new F[_N];
- _channel2 = new F[_N+2];
- */
-
- _output = new F[_Nw];
-
- _bitshuffle = new I[_N*2];
- _trigland = new F[_N*2];
-
- _Wanal = new F[_Nw];
- _Wsyn = new F[_Nw];
- _Hwin = new F[_Nw];
-
- init_rdft( _N, _bitshuffle, _trigland);
-
- if(_qual)
- makewindows( _Hwin, _Wanal, _Wsyn, _Nw, _N, _D, 0);
- else
- makehanning( _Hwin, _Wanal, _Wsyn, _Nw, _N, _D, 0,0);
-
- // ---------------------------------------------
-
- _shuffle_in = new I[_N2];
- _shuffle_out = new I[_N2];
-
- // calculate _max_bin
- ms_freq(_freq);
-
- reset_shuffle();
- }
-}
-
-V disarray::m_signal(I n,S *const *in,S *const *out)
+V disarray::Transform(I _N2,S *const *in)
{
- /* declare working variables */
- I i, j;
- const I _D = n,_N = _D*_nmult,_Nw = _N,_N2 = _N/2,_Nw2 = _Nw/2;
-
- _inCount += _D;
-
- for ( j = 0 ; j < _N-_D ; j++ )
- _input1[j] = _input1[j+_D];
- for (i = 0; j < _N; j++,i++ )
- _input1[j] = in[0][i];
-
- fold( _input1, _Wanal, _Nw, _buffer1, _N, _inCount );
- rdft( _N, 1, _buffer1, _bitshuffle, _trigland );
-
- // ---- BEGIN --------------------------------
-
leanconvert( _buffer1, _channel1, _N2 );
- for( i = 0; i < _shuffle_count ; i++){
+ for(I i = 0; i < _shuffle_count ; i++){
F tmp = _channel1[ _shuffle_in[ i ] * 2 ];
_channel1[ _shuffle_in[ i ] * 2] = _channel1[ _shuffle_out[ i ] * 2];
_channel1[ _shuffle_out[ i ] * 2] = tmp;
}
leanunconvert( _channel1, _buffer1, _N2 );
-
- // ---- END --------------------------------
-
- rdft( _N, -1, _buffer1, _bitshuffle, _trigland );
- overlapadd( _buffer1, _N, _Wsyn, _output, _Nw, _inCount);
-
- const F mult = 1./_N;
- for ( j = 0; j < _D; j++ )
- out[0][j] = _output[j] * mult;
-
- for ( j = 0; j < _N-_D; j++ )
- _output[j] = _output[j+_D];
- for (; j < _N; j++ )
- _output[j] = 0.;
}
V disarray::reset_shuffle()
{
- const I _N2 = Blocksize()*_nmult/2;
+ const I _N2 = Blocksize()*Mult()/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 7db3f4f0..336f9c8e 100644
--- a/externals/grill/fftease/src/drown~.cpp
+++ b/externals/grill/fftease/src/drown~.cpp
@@ -13,146 +13,30 @@ WARRANTIES, see the file, "license.txt," in this distribution.
#include <stdlib.h>
class drown:
- public flext_dsp
+ public fftease
{
- FLEXT_HEADER_S(drown,flext_dsp,setup)
+ FLEXT_HEADER(drown,fftease)
public:
drown(I argc,const t_atom *argv);
- ~drown();
protected:
- virtual V m_dsp(I n,S *const *in,S *const *out);
- virtual V m_signal(I n,S *const *in,S *const *out);
-
- I blsz;
- F smprt;
-
- F *_input1,*_input2;
- F *_buffer1,*_buffer2;
- F *_channel1,*_channel2;
- F *_output;
-// F *_trigland;
- // I *_bitshuffle;
- F *_Wanal,*_Wsyn,*_Hwin;
-
- I _inCount,_nmult;
-
- // -----------------------------
-
-private:
- V Clear();
- V Delete();
-
- static V setup(t_classid c);
+ virtual V Transform(I n,S *const *in);
};
FLEXT_LIB_DSP_V("fftease, drown~",drown)
-V drown::setup(t_classid c)
-{
-}
-
-
drown::drown(I argc,const t_atom *argv):
- blsz(0),smprt(0),_nmult(4)
+ fftease(4,false,true,false)
{
- Clear();
-
AddInSignal("Messages and input signal");
AddInSignal("Threshold generator signal");
AddInSignal("Multiplier signal for weak bins");
AddOutSignal("Transformed signal");
}
-drown::~drown()
-{
- Delete();
-}
-
-V drown::Clear()
-{
- _input1 = _input2 = NULL;
- _buffer1 = _buffer2 = NULL;
- _channel1 = _channel2 = NULL;
- _output = NULL;
-/*
- _bitshuffle = NULL;
- _trigland = NULL;
-*/
- _Hwin = NULL;
- _Wanal = _Wsyn = NULL;
-
- // -----------------------------
-
-}
-
-V drown::Delete()
-{
- if(_input1) delete[] _input1;
- if(_buffer1) delete[] _buffer1;
- if(_channel1) delete[] _channel1;
-/*
- if(_input2) delete[] _input2;
- if(_buffer2) delete[] _buffer2;
- if(_channel2) delete[] _channel2;
-*/
- if(_output) delete[] _output;
-/*
- if(_bitshuffle) delete[] _bitshuffle;
- if(_trigland) delete[] _trigland;
-*/
- if(_Wanal) delete[] _Wanal;
- if(_Wsyn) delete[] _Wsyn;
- if(_Hwin) delete[] _Hwin;
-
- // -----------------------------
-
-}
-
-
-V drown::m_dsp(I n,S *const *,S *const *)
-{
- const I _D = n;
- const F _R = Samplerate();
-
- if(_D != blsz || _R != smprt) {
- blsz = _D;
- smprt = _R;
-
- Delete();
- // ---------------------------------------------
-
- const int _N = _D*_nmult,_Nw = _N,_Nw2 = _Nw>>1,_N2 = _N>>1;
-
- _inCount = -_Nw;
-
- _input1 = new F[_Nw];
- _buffer1 = new F[_N];
- _channel1 = new F[_N+2];
- /*
- _input2 = new F[_Nw];
- _buffer2 = new F[_N];
- _channel2 = new F[_N+2];
- */
-
- _output = new F[_Nw];
-
- /*
- _bitshuffle = new I[_N*2];
- _trigland = new F[_N*2];
- init_rdft( _N, _bitshuffle, _trigland);
- */
-
- _Wanal = new F[_Nw];
- _Wsyn = new F[_Nw];
- _Hwin = new F[_Nw];
- makewindows( _Hwin, _Wanal, _Wsyn, _Nw, _N, _D, 0);
- }
-}
-
/* helper function */
static void nudist( float *_S, float *_C, float threshold, float fmult, int N2 )
@@ -180,48 +64,12 @@ static void nudist( float *_S, float *_C, float threshold, float fmult, int N2 )
}
-V drown::m_signal(I n,S *const *in,S *const *out)
+V drown::Transform(I _N2,S *const *in)
{
- /* declare working variables */
- I i, j;
- const I _D = n,_N = _D*_nmult,_Nw = _N,_N2 = _N/2,_Nw2 = _Nw/2;
-
- _inCount += _D;
-
- for ( j = 0 ; j < _N-_D ; j++ )
- _input1[j] = _input1[j+_D];
- for (i = 0; j < _N; j++,i++ )
- _input1[j] = in[0][i];
-
- fold( _input1, _Wanal, _Nw, _buffer1, _N, _inCount );
-
-// rdft( _N, 1, _buffer1, _bitshuffle, _trigland );
- rfft( _buffer1, _N2, 1);
-
- // ---- BEGIN --------------------------------
-
- {
- // only first value of the signal vectors
- const F thresh = in[1][0],mult = in[2][0];
-
- nudist( _buffer1, _channel1, thresh, mult, _N2 );
- }
-
- // ---- END --------------------------------
-
- rfft( _buffer1, _N2, 0);
-// rdft( _N, -1, _buffer1, _bitshuffle, _trigland );
-
- overlapadd( _buffer1, _N, _Wsyn, _output, _Nw, _inCount);
-
- const F mult = 1./_N;
- for ( j = 0; j < _D; j++ )
- out[0][j] = _output[j] * mult;
+ // only first value of the signal vectors
+ const F thresh = in[1][0],mult = in[2][0];
- for ( j = 0; j < _N-_D; j++ )
- _output[j] = _output[j+_D];
- for (; j < _N; j++ )
- _output[j] = 0.;
+ nudist( _buffer1, _channel1, thresh, mult, _N2 );
}
diff --git a/externals/grill/fftease/src/ether~.cpp b/externals/grill/fftease/src/ether~.cpp
index 12a0d359..e04efaec 100644
--- a/externals/grill/fftease/src/ether~.cpp
+++ b/externals/grill/fftease/src/ether~.cpp
@@ -13,41 +13,21 @@ WARRANTIES, see the file, "license.txt," in this distribution.
#include <stdlib.h>
class ether:
- public flext_dsp
+ public fftease
{
- FLEXT_HEADER_S(ether,flext_dsp,setup)
+ FLEXT_HEADER_S(ether,fftease,setup)
public:
ether(I argc,const t_atom *argv);
- ~ether();
protected:
- virtual V m_dsp(I n,S *const *in,S *const *out);
- virtual V m_signal(I n,S *const *in,S *const *out);
-
- I blsz;
- F smprt;
-
- F *_input1,*_input2;
- F *_buffer1,*_buffer2;
- F *_channel1,*_channel2;
- F *_output;
- F *_trigland;
- I *_bitshuffle;
- F *_Wanal,*_Wsyn,*_Hwin;
-
- I _inCount,_nmult;
-
- // -----------------------------
+ virtual V Transform(I n,S *const *in);
BL _qual,_invert;
F _threshMult;
private:
- V Clear();
- V Delete();
-
static V setup(t_classid c);
@@ -66,7 +46,7 @@ V ether::setup(t_classid c)
ether::ether(I argc,const t_atom *argv):
- blsz(0),smprt(0),
+ fftease(2,true,true,true),
_qual(false),_threshMult(0),_invert(false)
{
/* parse and set object's options given */
@@ -77,131 +57,21 @@ ether::ether(I argc,const t_atom *argv):
post("%s - Quality must be a boolean value - set to %0i",thisName(),_qual?1:0);
}
- _nmult = _qual?4:2;
-
- Clear();
+ _mult = _qual?4:2;
+ _window = _qual;
AddInSignal("Messages and input signal");
AddInSignal("Reference signal");
AddOutSignal("Transformed signal");
}
-ether::~ether()
-{
- Delete();
-}
-
-V ether::Clear()
-{
- _input1 = _input2 = NULL;
- _buffer1 = _buffer2 = NULL;
- _channel1 = _channel2 = NULL;
- _output = NULL;
-
- _bitshuffle = NULL;
- _trigland = NULL;
-
- _Hwin = NULL;
- _Wanal = _Wsyn = NULL;
-
- // -----------------------------
-}
-
-V ether::Delete()
-{
- if(_input1) delete[] _input1;
- if(_buffer1) delete[] _buffer1;
- if(_channel1) delete[] _channel1;
-
- if(_input2) delete[] _input2;
- if(_buffer2) delete[] _buffer2;
- if(_channel2) delete[] _channel2;
-
- if(_output) delete[] _output;
-
- if(_bitshuffle) delete[] _bitshuffle;
- if(_trigland) delete[] _trigland;
-
- if(_Wanal) delete[] _Wanal;
- if(_Wsyn) delete[] _Wsyn;
- if(_Hwin) delete[] _Hwin;
-
- // -----------------------------
-
-}
-
-
-V ether::m_dsp(I n,S *const *,S *const *)
-{
- const I _D = n;
- const F _R = Samplerate();
-
- if(_D != blsz || _R != smprt) {
- blsz = _D;
- smprt = _R;
-
- Delete();
- // ---------------------------------------------
-
- const int _N = _D*_nmult,_Nw = _N,_Nw2 = _Nw>>1,_N2 = _N>>1;
-
- _inCount = -_Nw;
-
- _input1 = new F[_Nw];
- _buffer1 = new F[_N];
- _channel1 = new F[_N+2];
-
- _input2 = new F[_Nw];
- _buffer2 = new F[_N];
- _channel2 = new F[_N+2];
-
- _output = new F[_Nw];
-
- _bitshuffle = new I[_N*2];
- _trigland = new F[_N*2];
-
- _Wanal = new F[_Nw];
- _Wsyn = new F[_Nw];
- _Hwin = new F[_Nw];
-
- init_rdft( _N, _bitshuffle, _trigland);
-
- if(_qual)
- makewindows( _Hwin, _Wanal, _Wsyn, _Nw, _N, _D, 0);
- else
- makehanning( _Hwin, _Wanal, _Wsyn, _Nw, _N, _D, 0,0);
- }
-}
-V ether::m_signal(I n,S *const *in,S *const *out)
+V ether::Transform(I _N2,S *const *in)
{
- /* declare working variables */
- I i, j;
- const I _D = n,_N = _D*_nmult,_Nw = _N,_N2 = _N/2,_Nw2 = _Nw/2;
-
- _inCount += _D;
-
- for ( j = 0 ; j < _N-_D ; j++ ) {
- _input1[j] = _input1[j+_D];
- _input2[j] = _input2[j+_D];
- }
- for (i = 0; j < _N; j++,i++ ) {
- _input1[j] = in[0][i];
- _input2[j] = in[1][i];
- }
-
- fold( _input1, _Wanal, _Nw, _buffer1, _N, _inCount );
- fold( _input2, _Wanal, _Nw, _buffer2, _N, _inCount );
-
- rdft( _N, 1, _buffer1, _bitshuffle, _trigland );
- rdft( _N, 1, _buffer2, _bitshuffle, _trigland );
-
- // ---- BEGIN --------------------------------
-
F threshMult = _threshMult;
if (threshMult == 0. ) threshMult = 1;
- for ( i = 0; i <= _N2; i++ ) {
+ for (I i = 0; i <= _N2; i++ ) {
int even = i<<1,odd = even + 1;
/* convert to polar coordinates from complex values */
@@ -233,19 +103,5 @@ V ether::m_signal(I n,S *const *in,S *const *out)
if (i != _N2 )
_buffer1[odd] = -_channel1[even] * sin( _channel1[odd] );
}
-
- // ---- END --------------------------------
-
- rdft( _N, -1, _buffer1, _bitshuffle, _trigland );
- overlapadd( _buffer1, _N, _Wsyn, _output, _Nw, _inCount);
-
- const F mult = 1./_N;
- for ( j = 0; j < _D; j++ )
- out[0][j] = _output[j] * mult;
-
- for ( j = 0; j < _N-_D; j++ )
- _output[j] = _output[j+_D];
- for (; j < _N; j++ )
- _output[j] = 0.;
}
diff --git a/externals/grill/fftease/src/fftease.cpp b/externals/grill/fftease/src/fftease.cpp
new file mode 100644
index 00000000..9e59faa1
--- /dev/null
+++ b/externals/grill/fftease/src/fftease.cpp
@@ -0,0 +1,185 @@
+/*
+
+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"
+
+
+fftease::fftease(I mult,BL stereo,BL window,BL bitshuf):
+ _mult(mult),_stereo(stereo),_window(window),_bitshuf(bitshuf),
+ _inCount(0),
+ blsz(0),smprt(0)
+{}
+
+fftease::~fftease() {}
+
+BL fftease::Init()
+{
+ BL ret = flext_dsp::Init();
+ Clear();
+ return ret;
+}
+
+V fftease::Exit()
+{
+ Delete();
+}
+
+V fftease::m_dsp(I n,S *const *in,S *const *out)
+{
+ const I _D = n;
+ const F sr = Samplerate();
+ if(_D != blsz || sr != smprt) {
+ blsz = _D;
+ smprt = sr;
+
+ Delete();
+ Set();
+ }
+}
+
+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;
+
+ /* fill our retaining buffers */
+ _inCount += _D;
+
+ if(_stereo) {
+ for(i = 0; i < _N-_D ; i++ ) {
+ _input1[i] = _input1[i+_D];
+ _input2[i] = _input2[i+_D];
+ }
+ for(I j = 0; i < _N; i++,j++) {
+ _input1[i] = in[0][j];
+ _input2[i] = in[1][j];
+ }
+ }
+ else {
+ for (i = 0 ; i < _N-_D ; i++ )
+ _input1[i] = _input1[i+_D];
+ for (I j = 0; i < _N; i++,j++ )
+ _input1[i] = in[0][j];
+ }
+
+ /* apply hamming window and fold our window buffer into the fft buffer */
+ fold( _input1, _Wanal, _Nw, _buffer1, _N, _inCount );
+ if(_stereo) fold( _input2, _Wanal, _Nw, _buffer2, _N, _inCount );
+
+ /* do an fft */
+ if(_bitshuf) {
+ rdft( _N, 1, _buffer1, _bitshuffle, _trigland );
+ if(_stereo) rdft( _N, 1, _buffer2, _bitshuffle, _trigland );
+ }
+ else {
+ rfft( _buffer1, _N2, 1);
+ if(_stereo) rfft( _buffer2, _N2,1);
+ }
+
+
+ // ---- BEGIN --------------------------------
+
+ Transform(_N2,in+(_stereo?1:2));
+
+ // ---- END --------------------------------
+
+
+ /* do an inverse fft */
+ if(_bitshuf)
+ rdft( _N, -1, _buffer1, _bitshuffle, _trigland );
+ else
+ rfft( _buffer1, _N2, 0);
+
+ /* dewindow our result */
+ overlapadd( _buffer1, _N, _Wsyn, _output, _Nw, _inCount);
+
+ /* set our output and adjust our retaining output buffer */
+ const F mult = 1./_N;
+ for ( i = 0; i < _D; i++ )
+ out[0][i] = _output[i] * mult;
+
+ for ( i = 0; i < _N-_D; i++ )
+ _output[i] = _output[i+_D];
+ for (; i < _N; i++ )
+ _output[i] = 0.;
+}
+
+
+void fftease::Set()
+{
+ /* preset the objects data */
+ const I _D = Blocksize(),_N = _D*Mult(),_Nw = _N,_N2 = _N/2,_Nw2 = _Nw/2;
+
+ _inCount = -_Nw;
+
+ /* assign memory to the buffers */
+ _input1 = new F[_Nw];
+ _buffer1 = new F[_N];
+ _channel1 = new F[_N+2];
+ if(_stereo) {
+ _input2 = new F[_Nw];
+ _buffer2 = new F[_N];
+ _channel2 = new F[_N+2];
+ }
+ _output = new F[_Nw];
+
+ if(_bitshuf) {
+ _bitshuffle = new I[_N*2];
+ _trigland = new F[_N*2];
+ init_rdft( _N, _bitshuffle, _trigland);
+ }
+
+ _Hwin = new F[_Nw];
+ _Wanal = new F[_Nw];
+ _Wsyn = new F[_Nw];
+ if(_window)
+ makewindows( _Hwin, _Wanal, _Wsyn, _Nw, _N, _D, 0);
+ else
+ makehanning( _Hwin, _Wanal, _Wsyn, _Nw, _N, _D, 0,0);
+}
+
+void fftease::Clear()
+{
+ _bitshuffle = NULL;
+ _trigland = NULL;
+ _input1 = _input2 = NULL;
+ _Hwin = NULL;
+ _Wanal = _Wsyn = NULL;
+ _buffer1 = _buffer2 = NULL;
+ _channel1 = _channel2 = NULL;
+ _output = NULL;
+}
+
+void fftease::Delete()
+{
+ if(_input1) delete[] _input1;
+ if(_buffer1) delete[] _buffer1;
+ if(_channel1) delete[] _channel1;
+ if(_stereo) {
+ if(_input2) delete[] _input2;
+ if(_buffer2) delete[] _buffer2;
+ if(_channel2) delete[] _channel2;
+ }
+ if(_output) delete[] _output;
+
+ if(_bitshuf) {
+ if(_bitshuffle) delete[] _bitshuffle;
+ if(_trigland) delete[] _trigland;
+ }
+
+ if(_Hwin) delete[] _Hwin;
+ if(_Wanal) delete[] _Wanal;
+ if(_Wsyn) delete[] _Wsyn;
+}
+
+
+
diff --git a/externals/grill/fftease/src/main.h b/externals/grill/fftease/src/main.h
index 6dbddf7e..d9746c71 100644
--- a/externals/grill/fftease/src/main.h
+++ b/externals/grill/fftease/src/main.h
@@ -37,4 +37,51 @@ WARRANTIES, see the file, "license.txt," in this distribution.
#define S t_sample
+
+class fftease:
+ public flext_dsp
+{
+ FLEXT_HEADER_S(fftease,flext_dsp,setup)
+
+public:
+ fftease(I mult,BL stereo,BL window,BL bitshuf);
+ virtual ~fftease();
+
+protected:
+
+ virtual BL Init();
+ virtual V Exit();
+
+ virtual V m_dsp(I n,S *const *in,S *const *out);
+ virtual V m_signal(I n,S *const *in,S *const *out);
+
+ virtual V Set();
+ virtual V Clear();
+ virtual V Delete();
+ virtual V Transform(I _N2,S *const *in) = 0;
+
+ I Mult() const { return _mult; }
+
+ F *_input1,*_input2;
+ F *_buffer1,*_buffer2;
+ F *_channel1,*_channel2;
+ F *_output;
+ F *_trigland;
+ I *_bitshuffle;
+ F *_Wanal,*_Wsyn,*_Hwin;
+
+ I _inCount;
+
+ I _mult;
+ BL _stereo,_window,_bitshuf;
+
+private:
+ I blsz;
+ F smprt;
+
+ static V setup(t_classid c) {}
+
+};
+
+
#endif