aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--externals/grill/fftease/pd/thresher.pd18
-rw-r--r--externals/grill/fftease/readme.txt9
-rw-r--r--externals/grill/fftease/src/fftease.cpp64
-rw-r--r--externals/grill/fftease/src/main.h9
-rw-r--r--externals/grill/fftease/src/pvoc~.cpp128
-rw-r--r--externals/grill/fftease/src/thresher~.cpp26
6 files changed, 201 insertions, 53 deletions
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 );
}