From 34ce52e8bec33c97e9413917f0f4b221fa0c6734 Mon Sep 17 00:00:00 2001 From: Thomas Grill Date: Thu, 13 Feb 2003 04:37:27 +0000 Subject: "" svn path=/trunk/; revision=395 --- externals/grill/dyn/readme.txt | 107 +- externals/grill/fftease/readme.txt | 194 +-- externals/grill/fftease/src/pvoc~.cpp | 2 + externals/grill/flext/config-pd-darwin.txt | 2 +- externals/grill/flext/config-pd-linux.txt | 2 +- externals/grill/flext/readme.txt | 12 +- externals/grill/flext/source/flatom_pr.cpp | 156 ++- externals/grill/flext/source/fldsp.cpp | 420 +++---- externals/grill/flext/source/flstdc.h | 424 +++---- externals/grill/flext/source/flstk.cpp | 12 - externals/grill/flext/source/flstk.h | 19 +- externals/grill/flext/source/flsupport.cpp | 313 ++--- externals/grill/flext/source/flsupport.h | 1678 +++++++++++++------------- externals/grill/flext/tutorial/pd/ex-stk2.pd | 9 +- externals/grill/flext/tutorial/stk1/stk1.dsp | 8 +- externals/grill/flext/tutorial/stk2/main.cpp | 18 +- externals/grill/flext/tutorial/stk2/stk2.dsp | 8 +- externals/grill/guitest/guitest.dsp | 8 +- externals/grill/pool/data.cpp | 10 +- externals/grill/pool/readme.txt | 158 +-- externals/grill/py/readme.txt | 244 ++-- externals/grill/xsample/readme.txt | 305 ++--- 22 files changed, 2059 insertions(+), 2050 deletions(-) diff --git a/externals/grill/dyn/readme.txt b/externals/grill/dyn/readme.txt index 5d8a32ae..7f8fa6bd 100644 --- a/externals/grill/dyn/readme.txt +++ b/externals/grill/dyn/readme.txt @@ -1,51 +1,56 @@ -dyn~ - dynamic object management for PD - -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. - - ----------------------------------------------------------------------------- - -The package should at least compile (and is tested) with the following compilers/platforms: - -pd - Windows: -------------- -o Microsoft Visual C++ 6: edit "config-pd-msvc.txt" & run "build-pd-msvc.bat" - - -pd - linux: ------------ -o GCC: edit "config-pd-linux.txt" & run "sh build-pd-linux.sh" - additional settings (e.g. target processor, compiler flags) can be made in makefile.pd-linux - - -pd - MacOSX: ------------ -o GCC: edit "config-pd-darwin.txt" & run "sh build-pd-darwin.sh" - additional settings (e.g. target processor, compiler flags) can be made in makefile.pd-darwin - ----------------------------------------------------------------------------- - -CHANGES: --------- - -0.0.2: -- give the dyn~ subcanvas a name (hard to access - for the wild scripters out there), - so that it is different from the canvas where dyn~ is in -- corrected names of message in- and out-proxies. -- manually retrigger DSP after loading an abstraction - -0.0.1: -- send loadbangs for loaded abstractions -- now use "dsp" message to enable dsp in sub-canvas (no need of canvas_addtolist, canvas_takefromlist any more) - - -0.0.0 - initial cvs version - - - -TODO: --------- -- support message boxes (do we need them?) -- Hash table for object tags +dyn~ - dynamic object management for PD + +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. + + +---------------------------------------------------------------------------- + +You will need the flext C++ layer for PD and Max/MSP externals to compile this. +see http://www.parasitaere-kapazitaeten.net/ext + +---------------------------------------------------------------------------- + +The package should at least compile (and is tested) with the following compilers/platforms: + +pd - Windows: +------------- +o Microsoft Visual C++ 6: edit "config-pd-msvc.txt" & run "build-pd-msvc.bat" + + +pd - linux: +----------- +o GCC: edit "config-pd-linux.txt" & run "sh build-pd-linux.sh" + additional settings (e.g. target processor, compiler flags) can be made in makefile.pd-linux + + +pd - MacOSX: +----------- +o GCC: edit "config-pd-darwin.txt" & run "sh build-pd-darwin.sh" + additional settings (e.g. target processor, compiler flags) can be made in makefile.pd-darwin + +---------------------------------------------------------------------------- + +CHANGES: +-------- + +0.0.2: +- give the dyn~ subcanvas a name (hard to access - for the wild scripters out there), + so that it is different from the canvas where dyn~ is in +- corrected names of message in- and out-proxies. +- manually retrigger DSP after loading an abstraction + +0.0.1: +- send loadbangs for loaded abstractions +- now use "dsp" message to enable dsp in sub-canvas (no need of canvas_addtolist, canvas_takefromlist any more) + + +0.0.0 - initial cvs version + + + +TODO: +-------- +- support message boxes (do we need them?) +- Hash table for object tags diff --git a/externals/grill/fftease/readme.txt b/externals/grill/fftease/readme.txt index 2ca7b808..88897ab4 100644 --- a/externals/grill/fftease/readme.txt +++ b/externals/grill/fftease/readme.txt @@ -1,93 +1,101 @@ -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. - - ----------------------------------------------------------------------------- - -The package should at least compile (and is tested) with the following compilers: - -pd - Windows: -------------- -OK o Microsoft Visual C++ 6: edit "config-pd-msvc.txt" & run "build-pd-msvc.bat" - -o Cygwin: edit "config-pd-cygwin.txt" & run "sh build-pd-cygwin.sh" - additional settings (e.g. target processor, compiler flags) can be made in makefile.pd-cygwin - - -pd - linux: ------------ -o GCC: edit "config-pd-linux.txt" & run "sh build-pd-linux.sh" - additional settings (e.g. target processor, compiler flags) can be made in makefile.pd-linux - - -pd - MacOSX: ------------ -OK o GCC: edit "config-pd-darwin.txt" & run "sh build-pd-darwin.sh" - additional settings (e.g. target processor, compiler flags) can be made in makefile.pd-darwin - - -Max/MSP - MacOS 9: ------------------- -OK o Metrowerks CodeWarrior V6: edit & use the "fftease.cw" project file - -You must have the following "Source Trees" defined: -"flext" - Pointing to the flext main directory -"Cycling74" - Pointing to the Cycling 74 SDK - - - -Max/MSP - MacOSX: ------------------- -OK o Metrowerks CodeWarrior V6: edit & use the "fftease.cw" project file - -You must have the following "Source Trees" defined: -"OS X Volume" - Pointing to your OSX boot drive -"flext" - Pointing to the flext main directory -"Cycling74 OSX" - Pointing to the Cycling 74 SDK for xmax -"MP SDK" - Pointing to the Multiprocessing SDK (for threading support) - - ----------------------------------------------------------------------------- - -PORTING NOTES: - -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 - - (jmax) BUG: a2 for i == N2 is calculated from buffer1 - - what about the class members for "correction"?! (superfluous) - -- dentist: - - tooth count ("teeth") is preserved and checked on every reshuffle - - use different knee correction - -- disarray: - - 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: - - possibility to change qual? - -- scrape: - - maxamp is computed (from spectral amplitudes) before these are set!! (function frowned) -> corrected - -- shapee: - - danger of div by 0... corrected - -- swinger: - - (jmax) phase is calculated from signal1 (instead of correct signal 2)!! - +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. + + +---------------------------------------------------------------------------- + +You will need the flext C++ layer for PD and Max/MSP externals to compile this. +see http://www.parasitaere-kapazitaeten.net/ext + +---------------------------------------------------------------------------- + + +BUILDING: +========= + + +pd - Windows: +------------- +OK o Microsoft Visual C++ 6: edit "config-pd-msvc.txt" & run "build-pd-msvc.bat" + +o Cygwin: edit "config-pd-cygwin.txt" & run "sh build-pd-cygwin.sh" + additional settings (e.g. target processor, compiler flags) can be made in makefile.pd-cygwin + + +pd - linux: +----------- +o GCC: edit "config-pd-linux.txt" & run "sh build-pd-linux.sh" + additional settings (e.g. target processor, compiler flags) can be made in makefile.pd-linux + + +pd - MacOSX: +----------- +OK o GCC: edit "config-pd-darwin.txt" & run "sh build-pd-darwin.sh" + additional settings (e.g. target processor, compiler flags) can be made in makefile.pd-darwin + + +Max/MSP - MacOS 9: +------------------ +OK o Metrowerks CodeWarrior V6: edit & use the "fftease.cw" project file + +You must have the following "Source Trees" defined: +"flext" - Pointing to the flext main directory +"Cycling74" - Pointing to the Cycling 74 SDK + + + +Max/MSP - MacOSX: +------------------ +OK o Metrowerks CodeWarrior V6: edit & use the "fftease.cw" project file + +You must have the following "Source Trees" defined: +"OS X Volume" - Pointing to your OSX boot drive +"flext" - Pointing to the flext main directory +"Cycling74 OSX" - Pointing to the Cycling 74 SDK for xmax +"MP SDK" - Pointing to the Multiprocessing SDK (for threading support) + + +---------------------------------------------------------------------------- + +PORTING NOTES: + +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 + - (jmax) BUG: a2 for i == N2 is calculated from buffer1 + - what about the class members for "correction"?! (superfluous) + +- dentist: + - tooth count ("teeth") is preserved and checked on every reshuffle + - use different knee correction + +- disarray: + - 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: + - possibility to change qual? + +- scrape: + - maxamp is computed (from spectral amplitudes) before these are set!! (function frowned) -> corrected + +- shapee: + - danger of div by 0... corrected + +- swinger: + - (jmax) phase is calculated from signal1 (instead of correct signal 2)!! + diff --git a/externals/grill/fftease/src/pvoc~.cpp b/externals/grill/fftease/src/pvoc~.cpp index d17cc576..43a576fa 100644 --- a/externals/grill/fftease/src/pvoc~.cpp +++ b/externals/grill/fftease/src/pvoc~.cpp @@ -90,6 +90,7 @@ pvoc::pvoc(I argc,const t_atom *argv): V pvoc::Transform(I _N,S *const *in) { + /* int freq,amp; int chan; @@ -122,6 +123,7 @@ V pvoc::Transform(I _N,S *const *in) index[chan] = address; } } + */ } diff --git a/externals/grill/flext/config-pd-darwin.txt b/externals/grill/flext/config-pd-darwin.txt index e017030e..b46ad593 100644 --- a/externals/grill/flext/config-pd-darwin.txt +++ b/externals/grill/flext/config-pd-darwin.txt @@ -2,7 +2,7 @@ # Copyright (c) 2001-2003 Thomas Grill (xovo@gmx.net) # -# where are the PD header files? +# where are the PD header files? (m_pd.h, m_imp.h, g_canvas.h) PDPATH=/usr/local/pd/src # where is the SndObj include directory? diff --git a/externals/grill/flext/config-pd-linux.txt b/externals/grill/flext/config-pd-linux.txt index 39ad5717..a201fdf2 100644 --- a/externals/grill/flext/config-pd-linux.txt +++ b/externals/grill/flext/config-pd-linux.txt @@ -5,7 +5,7 @@ # your c++ compiler (if it's different than g++) # CXX=g++ -# where are the PD header files? +# where are the PD header files? (m_pd.h, m_imp.h, g_canvas.h) # if it is a system include path (like /usr/local/include) # you should leave it blank (as e.g. g++ 3.2 complains about it) PDPATH= diff --git a/externals/grill/flext/readme.txt b/externals/grill/flext/readme.txt index 2196fb72..78d00184 100644 --- a/externals/grill/flext/readme.txt +++ b/externals/grill/flext/readme.txt @@ -29,7 +29,10 @@ o if you choose to compile with STK support you will need the respective package ---------------------------------------------------------------------------- -The package should at least compile (and is tested) with the following compilers: + +BUILDING & INSTALLING: +====================== + pd - Windows: ------------- @@ -61,20 +64,21 @@ With your project using flext, be sure to define "FLEXT_SYS=2". Max/MSP - MacOS 9: ------------------ -o Metrowerks CodeWarrior V6: edit & use the "flext.cw" project file +o Metrowerks CodeWarrior: edit & use the "flext.cw" project file You must have the following "Source Trees" defined: "flext" - Pointing to the flext main directory "Cycling74" - Pointing to the Cycling 74 SDK +"MP SDK" - Pointing to the Multiprocessing SDK (for threading support) With your project using flext, be sure to define "FLEXT_SYS=1" -- alternatively use the prefix file "flcwmax.h" +- alternatively use the prefix file "flcwmax.h" or "flcwmax-thr.h" for threading support. Max/MSP - MacOSX: ------------------ -o Metrowerks CodeWarrior V6: edit & use the "flext.cw" project file +o Metrowerks CodeWarrior: edit & use the "flext.cw" project file You must have the following "Source Trees" defined: "OS X Volume" - Pointing to your OSX boot drive diff --git a/externals/grill/flext/source/flatom_pr.cpp b/externals/grill/flext/source/flatom_pr.cpp index 7eeada93..b6cc0e5f 100644 --- a/externals/grill/flext/source/flatom_pr.cpp +++ b/externals/grill/flext/source/flatom_pr.cpp @@ -1,87 +1,69 @@ -/* - -flext - C++ layer for Max/MSP and pd (pure data) externals - -Copyright (c) 2001-2003 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. - -*/ - -/*! \file flatom_pr.cpp - \brief Definitions for printing and scanning the t_atom type. -*/ - -#include "flext.h" -#include -#include -#include -#include - -#ifdef __MWERKS__ -#define STD std -#else -#define STD -#endif - -void flext::PrintAtom(const t_atom &a,char *buf) -{ - if(IsFloat(a)) { -#if FLEXT_SYS == FLEXT_SYS_PD - if(a.a_w.w_float == (int)a.a_w.w_float) - STD::sprintf(buf,"%i",(int)GetFloat(a)); - else -#endif - STD::sprintf(buf,"%f",GetFloat(a)); - } - else if(IsInt(a)) - STD::sprintf(buf,"%i",GetInt(a)); - else if(IsPointer(a)) - STD::sprintf(buf,"%p",GetPointer(a)); - else if(IsSymbol(a)) - strcpy(buf,GetString(a)); - else if(IsNothing(a)) {} -#ifdef FLEXT_DEBUG - else - ERRINTERNAL(); -#endif -} - -bool flext::ScanAtom(t_atom &a,const char *buf) -{ - // skip whitespace - while(*buf && isspace(*buf)) ++buf; - if(!*buf) return false; - - char tmp[1024]; - strcpy(tmp,buf); - char *c = tmp; - - // check for word type (s = 0,1,2 ... int,float,symbol) - int s = 0; - for(; *c && !isspace(*c); ++c) { - if(!isdigit(*c)) - s = (*c != '.' || s == 1)?2:1; - } - - switch(s) { - case 0: // integer -#if FLEXT_SYS == FLEXT_SYS_MAX - SetInt(a,atol(tmp)); - break; -#endif - case 1: // float - SetFloat(a,(float)atof(tmp)); - break; - default: { // anything else is a symbol - char t = *c; *c = 0; - SetString(a,tmp); - *c = t; - break; - } - } - - return true; -} - - +/* + +flext - C++ layer for Max/MSP and pd (pure data) externals + +Copyright (c) 2001-2003 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. + +*/ + +/*! \file flatom_pr.cpp + \brief Definitions for printing and scanning the t_atom type. +*/ + +#include "flext.h" +#include +#include +#include +#include + +#ifdef __MWERKS__ +#define STD std +#else +#define STD +#endif + +void flext::PrintAtom(const t_atom &a,char *buf,int bufsz) +{ + GetAString(a,buf,bufsz?bufsz:100000); +} + +bool flext::ScanAtom(t_atom &a,const char *buf) +{ + // skip whitespace + while(*buf && isspace(*buf)) ++buf; + if(!*buf) return false; + + char tmp[1024]; + strcpy(tmp,buf); + char *c = tmp; + + // check for word type (s = 0,1,2 ... int,float,symbol) + int s = 0; + for(; *c && !isspace(*c); ++c) { + if(!isdigit(*c)) + s = (*c != '.' || s == 1)?2:1; + } + + switch(s) { + case 0: // integer +#if FLEXT_SYS == FLEXT_SYS_MAX + SetInt(a,atol(tmp)); + break; +#endif + case 1: // float + SetFloat(a,(float)atof(tmp)); + break; + default: { // anything else is a symbol + char t = *c; *c = 0; + SetString(a,tmp); + *c = t; + break; + } + } + + return true; +} + + diff --git a/externals/grill/flext/source/fldsp.cpp b/externals/grill/flext/source/fldsp.cpp index 64051008..a90545d2 100644 --- a/externals/grill/flext/source/fldsp.cpp +++ b/externals/grill/flext/source/fldsp.cpp @@ -1,210 +1,210 @@ -/* - -flext - C++ layer for Max/MSP and pd (pure data) externals - -Copyright (c) 2001-2003 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. - -*/ - -/*! \file fldsp.cpp - \brief Implementation of the flext dsp base class. -*/ - -#include "flext.h" -#include "flinternal.h" -#include - - - -// === flext_dsp ============================================== - -#if FLEXT_SYS == FLEXT_SYS_JMAX -const t_symbol *flext_dsp::dspsym = MakeSymbol("__flext_dspfun__"); -#endif - -void flext_dsp::Setup(t_classid id) -{ - t_class *c = getClass(id); - -#if FLEXT_SYS == FLEXT_SYS_MAX -// dsp_initclass(); - dsp_initboxclass(); - add_dsp(c,cb_dsp); -#elif FLEXT_SYS == FLEXT_SYS_PD - CLASS_MAINSIGNALIN(c,flext_hdr,defsig); // float messages going into the left inlet are converted to signal - add_dsp(c,cb_dsp); - add_method1(c,cb_enable,"enable",A_FLOAT); -#elif FLEXT_SYS == FLEXT_SYS_JMAX - fts_dsp_declare_function(dspsym,dspmeth); - fts_class_message_varargs(c, fts_s_put, cb_dsp); - fts_class_message_varargs(c, MakeSymbol("enable"), cb_enable); -#endif -} - -flext_dsp::flext_dsp(): -#if FLEXT_SYS == FLEXT_SYS_JMAX - srate(fts_dsp_get_sample_rate()), // should we set it? - blksz(fts_dsp_get_tick_size()), -#else - srate(sys_getsr()), // should we set it? - blksz(sys_getblksize()), -#endif -#if FLEXT_SYS == FLEXT_SYS_PD - chnsin(sys_get_inchannels()), - chnsout(sys_get_outchannels()), -#elif FLEXT_SYS == FLEXT_SYS_MAX - chnsin(sys_getch()), - chnsout(sys_getch()), -#elif FLEXT_SYS == FLEXT_SYS_JMAX - #pragma message("not implemented") - chnsin(0),chnsout(0), -#else -#error -#endif -#if FLEXT_SYS != FLEXT_SYS_MAX - dspon(true), -#endif - invecs(NULL),outvecs(NULL) -{ -#if FLEXT_SYS == FLEXT_SYS_JMAX - fts_dsp_object_init(thisHdr()); -#endif -} - - -flext_dsp::~flext_dsp() -{ -#if FLEXT_SYS == FLEXT_SYS_JMAX - fts_dsp_object_delete(thisHdr()); -#endif - if(invecs) delete[] invecs; - if(outvecs) delete[] outvecs; -} - -#if FLEXT_SYS == FLEXT_SYS_JMAX -void flext_dsp::dspmeth(fts_word_t *w) -{ -} -#else -t_int *flext_dsp::dspmeth(t_int *w) -{ - flext_dsp *obj = (flext_dsp *)w[1]; -#if FLEXT_SYS == FLEXT_SYS_MAX - if(!obj->thisHdr()->z_disabled) -#else - if(obj->dspon) -#endif - obj->m_signal((int)w[2],obj->invecs,obj->outvecs); - return w+3; -} -#endif - -#if FLEXT_SYS == FLEXT_SYS_JMAX -void flext_dsp::cb_dsp(fts_object_t *c, int winlet, fts_symbol_t s, int ac, const fts_atom_t *at) -#else -void flext_dsp::cb_dsp(t_class *c,t_signal **sp) -#endif -{ - flext_dsp *obj = thisObject(c); - - if(obj->CntInSig()+obj->CntOutSig() == 0) return; - - // store current dsp parameters -#if FLEXT_SYS == FLEXT_SYS_JMAX - fts_dsp_descr_t *dsp = (fts_dsp_descr_t *)fts_get_pointer(at+0); - obj->srate = fts_dsp_get_input_srate(dsp,0); - obj->blksz = fts_dsp_get_input_size(dsp,0); // is this guaranteed to be the same as sys_getblksize() ? -#else - obj->srate = sp[0]->s_sr; - obj->blksz = sp[0]->s_n; // is this guaranteed to be the same as sys_getblksize() ? -#endif - -#if FLEXT_SYS == FLEXT_SYS_PD - obj->chnsin = sys_get_inchannels(); - obj->chnsout = sys_get_outchannels(); -#elif FLEXT_SYS == FLEXT_SYS_MAX - obj->chnsin = obj->chnsout = sys_getch(); -#elif FLEXT_SYS == FLEXT_SYS_JMAX - #pragma message ("How to query the channels?") -#else -#error -#endif - - // store in and out signal vectors - int i,in = obj->CntInSig(),out = obj->CntOutSig(); - -#if FLEXT_SYS == FLEXT_SYS_PD - // min. 1 input channel! (CLASS_MAININLET in pd...) - if(!in) in = 1; -#endif - - if(obj->invecs) delete[] obj->invecs; - obj->invecs = new t_signalvec[in]; - for(i = 0; i < in; ++i) - obj->invecs[i] = -#if FLEXT_SYS == FLEXT_SYS_JMAX - fts_dsp_get_input_name(dsp,i); -#else - sp[i]->s_vec; -#endif - - if(obj->outvecs) delete[] obj->outvecs; - obj->outvecs = new t_signalvec[out]; - for(i = 0; i < out; ++i) - obj->outvecs[i] = -#if FLEXT_SYS == FLEXT_SYS_JMAX - fts_dsp_get_output_name(dsp,i); -#else - sp[in+i]->s_vec; -#endif - - // with the following call derived classes can do their eventual DSP setup - obj->m_dsp(obj->blksz,obj->invecs,obj->outvecs); - - // set the DSP function -#if FLEXT_SYS == FLEXT_SYS_JMAX - fts_atom_t args[2]; - fts_set_pointer(args+0,obj); - fts_set_int(args+1,obj->blksz); - fts_dsp_add_function(dspsym,2,args); -#else - dsp_add((t_dspmethod)dspmeth,2,obj,obj->blksz); -#endif -} - -/* -#if FLEXT_SYS == FLEXT_SYS_JMAX -void flext_dsp::cb_dsp_init(fts_object_t *c, int winlet, fts_symbol_t *s, int ac, const fts_atom_t *at) -{ - fts_dsp_add_object(c); -} - -void flext_dsp::cb_dsp_delete(fts_object_t *c, int winlet, fts_symbol_t *s, int ac, const fts_atom_t *at) -{ - fts_dsp_remove_object(c); -} -#endif -*/ - -void flext_dsp::m_dsp(int /*n*/,t_signalvec const * /*insigs*/,t_signalvec const * /*outsigs*/) {} - -void flext_dsp::m_signal(int n,t_sample *const * /*insigs*/,t_sample *const *outs) -{ - for(int i = 0; i < CntOutSig(); ++i) ZeroMem(outs[i],n*sizeof(*outs[i])); -} - -#if FLEXT_SYS != FLEXT_SYS_MAX - -#if FLEXT_SYS == FLEXT_SYS_PD -void flext_dsp::cb_enable(t_class *c,t_float on) { thisObject(c)->m_enable(on != 0); } -#elif FLEXT_SYS == FLEXT_SYS_JMAX -void flext_dsp::cb_enable(fts_object_t *c, int winlet, fts_symbol_t s, int ac, const fts_atom_t *at) -{ thisObject(c)->m_enable(fts_get_int(at+0) != 0); } -#endif - -void flext_dsp::m_enable(bool en) { dspon = en; } -#endif - - +/* + +flext - C++ layer for Max/MSP and pd (pure data) externals + +Copyright (c) 2001-2003 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. + +*/ + +/*! \file fldsp.cpp + \brief Implementation of the flext dsp base class. +*/ + +#include "flext.h" +#include "flinternal.h" +#include + + + +// === flext_dsp ============================================== + +#if FLEXT_SYS == FLEXT_SYS_JMAX +const t_symbol *flext_dsp::dspsym = MakeSymbol("__flext_dspfun__"); +#endif + +void flext_dsp::Setup(t_classid id) +{ + t_class *c = getClass(id); + +#if FLEXT_SYS == FLEXT_SYS_MAX +// dsp_initclass(); + dsp_initboxclass(); + add_dsp(c,cb_dsp); +#elif FLEXT_SYS == FLEXT_SYS_PD + CLASS_MAINSIGNALIN(c,flext_hdr,defsig); // float messages going into the left inlet are converted to signal + add_dsp(c,cb_dsp); + add_method1(c,cb_enable,"enable",A_FLOAT); +#elif FLEXT_SYS == FLEXT_SYS_JMAX + fts_dsp_declare_function(dspsym,dspmeth); + fts_class_message_varargs(c, fts_s_put, cb_dsp); + fts_class_message_varargs(c, MakeSymbol("enable"), cb_enable); +#endif +} + +flext_dsp::flext_dsp(): +#if FLEXT_SYS == FLEXT_SYS_JMAX + srate(fts_dsp_get_sample_rate()), // should we set it? + blksz(fts_dsp_get_tick_size()), +#else + srate(sys_getsr()), // should we set it? + blksz(sys_getblksize()), +#endif +#if FLEXT_SYS == FLEXT_SYS_PD + chnsin(sys_get_inchannels()), + chnsout(sys_get_outchannels()), +#elif FLEXT_SYS == FLEXT_SYS_MAX + chnsin(sys_getch()), + chnsout(sys_getch()), +#elif FLEXT_SYS == FLEXT_SYS_JMAX + #pragma message("not implemented") + chnsin(0),chnsout(0), +#else +#error +#endif +#if FLEXT_SYS != FLEXT_SYS_MAX + dspon(true), +#endif + invecs(NULL),outvecs(NULL) +{ +#if FLEXT_SYS == FLEXT_SYS_JMAX + fts_dsp_object_init(thisHdr()); +#endif +} + + +flext_dsp::~flext_dsp() +{ +#if FLEXT_SYS == FLEXT_SYS_JMAX + fts_dsp_object_delete(thisHdr()); +#endif + if(invecs) delete[] invecs; + if(outvecs) delete[] outvecs; +} + +#if FLEXT_SYS == FLEXT_SYS_JMAX +void flext_dsp::dspmeth(fts_word_t *w) +{ +} +#else +t_int *flext_dsp::dspmeth(t_int *w) +{ + flext_dsp *obj = (flext_dsp *)w[1]; +#if FLEXT_SYS == FLEXT_SYS_MAX + if(!obj->thisHdr()->z_disabled) +#else + if(obj->dspon) +#endif + obj->m_signal((int)w[2],obj->invecs,obj->outvecs); + return w+3; +} +#endif + +#if FLEXT_SYS == FLEXT_SYS_JMAX +void flext_dsp::cb_dsp(fts_object_t *c, int winlet, fts_symbol_t s, int ac, const fts_atom_t *at) +#else +void flext_dsp::cb_dsp(t_class *c,t_signal **sp) +#endif +{ + flext_dsp *obj = thisObject(c); + + if(obj->CntInSig()+obj->CntOutSig() == 0) return; + + // store current dsp parameters +#if FLEXT_SYS == FLEXT_SYS_JMAX + fts_dsp_descr_t *dsp = (fts_dsp_descr_t *)fts_get_pointer(at+0); + obj->srate = fts_dsp_get_input_srate(dsp,0); + obj->blksz = fts_dsp_get_input_size(dsp,0); // is this guaranteed to be the same as sys_getblksize() ? +#else + obj->srate = sp[0]->s_sr; + obj->blksz = sp[0]->s_n; // is this guaranteed to be the same as sys_getblksize() ? +#endif + +#if FLEXT_SYS == FLEXT_SYS_PD + obj->chnsin = sys_get_inchannels(); + obj->chnsout = sys_get_outchannels(); +#elif FLEXT_SYS == FLEXT_SYS_MAX + obj->chnsin = obj->chnsout = sys_getch(); +#elif FLEXT_SYS == FLEXT_SYS_JMAX + #pragma message ("How to query the channels?") +#else +#error +#endif + + // store in and out signal vectors + int i,in = obj->CntInSig(),out = obj->CntOutSig(); + +#if FLEXT_SYS == FLEXT_SYS_PD + // min. 1 input channel! (CLASS_MAININLET in pd...) + if(!in) in = 1; +#endif + + if(obj->invecs) delete[] obj->invecs; + obj->invecs = new t_signalvec[in]; + for(i = 0; i < in; ++i) + obj->invecs[i] = +#if FLEXT_SYS == FLEXT_SYS_JMAX + fts_dsp_get_input_name(dsp,i); +#else + sp[i]->s_vec; +#endif + + if(obj->outvecs) delete[] obj->outvecs; + obj->outvecs = new t_signalvec[out]; + for(i = 0; i < out; ++i) + obj->outvecs[i] = +#if FLEXT_SYS == FLEXT_SYS_JMAX + fts_dsp_get_output_name(dsp,i); +#else + sp[in+i]->s_vec; +#endif + + // with the following call derived classes can do their eventual DSP setup + obj->m_dsp(obj->blksz,obj->invecs,obj->outvecs); + + // set the DSP function +#if FLEXT_SYS == FLEXT_SYS_JMAX + fts_atom_t args[2]; + fts_set_pointer(args+0,obj); + fts_set_int(args+1,obj->blksz); + fts_dsp_add_function(dspsym,2,args); +#else + dsp_add((t_dspmethod)dspmeth,2,obj,obj->blksz); +#endif +} + +/* +#if FLEXT_SYS == FLEXT_SYS_JMAX +void flext_dsp::cb_dsp_init(fts_object_t *c, int winlet, fts_symbol_t *s, int ac, const fts_atom_t *at) +{ + fts_dsp_add_object(c); +} + +void flext_dsp::cb_dsp_delete(fts_object_t *c, int winlet, fts_symbol_t *s, int ac, const fts_atom_t *at) +{ + fts_dsp_remove_object(c); +} +#endif +*/ + +void flext_dsp::m_dsp(int /*n*/,t_signalvec const * /*insigs*/,t_signalvec const * /*outsigs*/) {} + +void flext_dsp::m_signal(int n,t_sample *const * /*insigs*/,t_sample *const *outs) +{ + for(int i = 0; i < CntOutSig(); ++i) ZeroSamples(outs[i],n); +} + +#if FLEXT_SYS != FLEXT_SYS_MAX + +#if FLEXT_SYS == FLEXT_SYS_PD +void flext_dsp::cb_enable(t_class *c,t_float on) { thisObject(c)->m_enable(on != 0); } +#elif FLEXT_SYS == FLEXT_SYS_JMAX +void flext_dsp::cb_enable(fts_object_t *c, int winlet, fts_symbol_t s, int ac, const fts_atom_t *at) +{ thisObject(c)->m_enable(fts_get_int(at+0) != 0); } +#endif + +void flext_dsp::m_enable(bool en) { dspon = en; } +#endif + + diff --git a/externals/grill/flext/source/flstdc.h b/externals/grill/flext/source/flstdc.h index 873f4243..44d2dc03 100644 --- a/externals/grill/flext/source/flstdc.h +++ b/externals/grill/flext/source/flstdc.h @@ -1,212 +1,212 @@ -/* - -flext - C++ layer for Max/MSP and pd (pure data) externals - -Copyright (c) 2001-2003 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. - -*/ - -/*! \file flstdc.h - \brief Definitions to unite Max/MSP and PD notions - - This file contains a few definitions to unite a few of the notions that - once drifted apart in Max and PD. It is not elegant but helps. -*/ - -#ifndef __FLEXT_STDC_H -#define __FLEXT_STDC_H - -// PD stuff - -#if FLEXT_SYS == FLEXT_SYS_PD - -/* PD definitions start here */ - -#ifdef _MSC_VER - #pragma warning (push) - #pragma warning (disable:4091 4005) -#endif - -#if FLEXT_OS == FLEXT_OS_WIN && !defined(NT) -#define NT -#endif - -extern "C" { - // Include the relevant PD header files - #ifdef FLEXT_DEBUG - #include // for easier debugging - #else - #include - #endif -} - -#ifdef _MSC_VER - #pragma warning (pop) -#endif - -#ifdef cabs -#undef cabs // this is defined in m_pd.h (clashes with math.h in MacOSX) -#endif - -typedef t_object t_sigobj; -typedef t_gpointer *t_ptrtype; - -typedef t_float t_flint; -typedef t_symbol *t_symtype; -typedef t_class **t_thing; - -typedef t_clock t_qelem; - -#define A_NOTHING A_NULL -#define A_FLINT A_FLOAT -#define A_DEFFLINT A_DEFFLOAT - - -#elif FLEXT_SYS == FLEXT_SYS_MAX - -/* Max/MSP definitions start here */ - - -// Include the relevant Max/MSP header files - -#if FLEXT_OS == FLEXT_OS_MAC - #ifndef __MRC__ - #define powerc - #endif - #define __MOTO__ 0 - - #include -#elif FLEXT_OS == FLEXT_OS_WIN - #define WIN_VERSION 1 -#endif - -extern "C" -{ - #include "ext.h" - #include "ext_user.h" - #include "z_dsp.h" -} - -#undef WIN_VERSION - - -typedef t_pxbox t_sigobj; // that's the all-in-one object type of Max/MSP (not very memory-efficent, i guess) -typedef t_patcher t_canvas; - -typedef t_int t_flint; -typedef t_symbol *t_symtype; -typedef t_object *t_thing; - -typedef qelem t_qelem; - -typedef method t_method; -typedef method t_newmethod; -typedef int t_atomtype; - -typedef struct clock t_clock; -typedef void t_binbuf; - -#undef clock_free -#define clock_free(tick) freeobject((object *)tick) - -#define A_NULL A_NOTHING -#define A_DEFFLINT A_DEFLONG - -#ifndef A_INT -#define A_INT A_LONG -#endif - -#ifndef A_SYMBOL -#define A_SYMBOL A_SYM -#endif - - -#elif FLEXT_SYS == FLEXT_SYS_JMAX - -extern "C" { - // Wow, the jMax developers made excessive use of C++ reserved words - // good hit! - #define typeid c_typeid_ - #define template c_template_ - #define this c_this_ - #define class c_class_ - - #include - - // undefine them again - #undef typeid - #undef template - #undef this - #undef class -} - -typedef fts_dsp_object t_sigobj; -typedef void t_canvas; // decide type later on - -typedef char t_symbol; -typedef fts_atom_t t_atom; -typedef fts_class_t t_class; -typedef float t_sample; // is there no sample type in jMax? - -typedef fts_timebase_entry_t t_clock; -typedef fts_timebase_entry_t t_qelem; - -#endif // FLEXT_SYS - - -// general definitions - -typedef t_symbol *t_symptr; - - -// ------------------------- - -#ifdef _LOG - -/* If _LOG is defined implement logging */ -#define LOG(s) post(s) -#define LOG1(s,v1) post(s,v1) -#define LOG2(s,v1,v2) post(s,v1,v2) -#define LOG3(s,v1,v2,v3) post(s,v1,v2,v3) -#define LOG4(s,v1,v2,v3,v4) post(s,v1,v2,v3,v4) -#define LOG5(s,v1,v2,v3,v4,v5) post(s,v1,v2,v3,v4,v5) - - -#else - -/* If _LOG is not defined avoid logging */ -#define LOG(s) ((void)0) -#define LOG1(s,v1) ((void)0) -#define LOG2(s,v1,v2) ((void)0) -#define LOG3(s,v1,v2,v3) ((void)0) -#define LOG4(s,v1,v2,v3,v4) ((void)0) -#define LOG5(s,v1,v2,v3,v4,v5) ((void)0) - -#endif - -#ifdef FLEXT_DEBUG -#define ASSERT(b) ((void)(!(b)?(error("Assertion failed: " #b " - in " __FILE__ " line %i",(int)__LINE__),0):0)) -#else -#define ASSERT(b) ((void)0) -#endif - -#define ERRINTERNAL() error("flext: Internal error in file " __FILE__ ", line %i - please report",(int)__LINE__) - - -/* Set the right calling convention (and exporting) for the OS */ - -#ifdef _MSC_VER - #ifdef FLEXT_SHARED - #define FLEXT_SHARE __declspec(dllexport) - #else - #define FLEXT_SHARE - #endif - #define FLEXT_EXT __declspec(dllexport) -#else // other OS's - #define FLEXT_SHARE - #define FLEXT_EXT -#endif - -#endif +/* + +flext - C++ layer for Max/MSP and pd (pure data) externals + +Copyright (c) 2001-2003 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. + +*/ + +/*! \file flstdc.h + \brief Definitions to unite Max/MSP and PD notions + + This file contains a few definitions to unite a few of the notions that + once drifted apart in Max and PD. It is not elegant but helps. +*/ + +#ifndef __FLEXT_STDC_H +#define __FLEXT_STDC_H + +// PD stuff + +#if FLEXT_SYS == FLEXT_SYS_PD + +/* PD definitions start here */ + +#ifdef _MSC_VER + #pragma warning (push) + #pragma warning (disable:4091 4005) +#endif + +#if FLEXT_OS == FLEXT_OS_WIN && !defined(NT) +#define NT +#endif + +extern "C" { + // Include the relevant PD header files + #ifdef FLEXT_DEBUG + #include // for easier debugging + #else + #include + #endif +} + +#ifdef _MSC_VER + #pragma warning (pop) +#endif + +#ifdef cabs +#undef cabs // this is defined in m_pd.h (clashes with math.h in MacOSX) +#endif + +typedef t_object t_sigobj; +typedef t_gpointer *t_ptrtype; + +typedef t_float t_flint; +typedef t_symbol *t_symtype; +typedef t_class **t_thing; + +typedef t_clock t_qelem; + +#define A_NOTHING A_NULL +#define A_FLINT A_FLOAT +#define A_DEFFLINT A_DEFFLOAT + + +#elif FLEXT_SYS == FLEXT_SYS_MAX + +/* Max/MSP definitions start here */ + + +// Include the relevant Max/MSP header files + +#if FLEXT_OS == FLEXT_OS_MAC + #ifndef __MRC__ + #define powerc + #endif + #define __MOTO__ 0 + + #include +#elif FLEXT_OS == FLEXT_OS_WIN + #define WIN_VERSION 1 +#endif + +extern "C" +{ + #include "ext.h" + #include "ext_user.h" + #include "z_dsp.h" +} + +#undef WIN_VERSION + + +typedef t_pxbox t_sigobj; // that's the all-in-one object type of Max/MSP (not very memory-efficent, i guess) +typedef t_patcher t_canvas; + +typedef t_int t_flint; +typedef t_symbol *t_symtype; +typedef t_object *t_thing; + +typedef qelem t_qelem; + +typedef method t_method; +typedef method t_newmethod; +typedef int t_atomtype; + +typedef struct clock t_clock; +typedef void t_binbuf; + +#undef clock_free +#define clock_free(tick) freeobject((object *)tick) + +#define A_NULL A_NOTHING +#define A_DEFFLINT A_DEFLONG + +#ifndef A_INT +#define A_INT A_LONG +#endif + +#ifndef A_SYMBOL +#define A_SYMBOL A_SYM +#endif + + +#elif FLEXT_SYS == FLEXT_SYS_JMAX + +extern "C" { + // Wow, the jMax developers made excessive use of C++ reserved words + // good hit! + #define typeid c_typeid_ + #define template c_template_ + #define this c_this_ + #define class c_class_ + + #include + + // undefine them again + #undef typeid + #undef template + #undef this + #undef class +} + +typedef fts_dsp_object t_sigobj; +typedef void t_canvas; // decide type later on + +typedef char t_symbol; +typedef fts_atom_t t_atom; +typedef fts_class_t t_class; +typedef float t_sample; // is there no sample type in jMax? + +typedef fts_timebase_entry_t t_clock; +typedef fts_timebase_entry_t t_qelem; + +#endif // FLEXT_SYS + + +// general definitions + +typedef t_symbol *t_symptr; + + +// ------------------------- + +#ifdef _LOG + +/* If _LOG is defined implement logging */ +#define LOG(s) post(s) +#define LOG1(s,v1) post(s,v1) +#define LOG2(s,v1,v2) post(s,v1,v2) +#define LOG3(s,v1,v2,v3) post(s,v1,v2,v3) +#define LOG4(s,v1,v2,v3,v4) post(s,v1,v2,v3,v4) +#define LOG5(s,v1,v2,v3,v4,v5) post(s,v1,v2,v3,v4,v5) + + +#else + +/* If _LOG is not defined avoid logging */ +#define LOG(s) ((void)0) +#define LOG1(s,v1) ((void)0) +#define LOG2(s,v1,v2) ((void)0) +#define LOG3(s,v1,v2,v3) ((void)0) +#define LOG4(s,v1,v2,v3,v4) ((void)0) +#define LOG5(s,v1,v2,v3,v4,v5) ((void)0) + +#endif + +#ifdef FLEXT_DEBUG +#define FLEXT_ASSERT(b) ((void)(!(b)?(error("Assertion failed: " #b " - in " __FILE__ " line %i",(int)__LINE__),0):0)) +#else +#define FLEXT_ASSERT(b) ((void)0) +#endif + +#define ERRINTERNAL() error("flext: Internal error in file " __FILE__ ", line %i - please report",(int)__LINE__) + + +/* Set the right calling convention (and exporting) for the OS */ + +#ifdef _MSC_VER + #ifdef FLEXT_SHARED + #define FLEXT_SHARE __declspec(dllexport) + #else + #define FLEXT_SHARE + #endif + #define FLEXT_EXT __declspec(dllexport) +#else // other OS's + #define FLEXT_SHARE + #define FLEXT_EXT +#endif + +#endif diff --git a/externals/grill/flext/source/flstk.cpp b/externals/grill/flext/source/flstk.cpp index 58fd192e..42f2fa85 100644 --- a/externals/grill/flext/source/flstk.cpp +++ b/externals/grill/flext/source/flstk.cpp @@ -95,12 +95,6 @@ flext_stk::Input::Input(const t_sample *b,int v): index(0) {} -MY_FLOAT flext_stk::Input::tick() -{ - if(++index >= vecsz) index = 0; - return lastOut(); -} - MY_FLOAT *flext_stk::Input::tick(MY_FLOAT *vector,unsigned int vectorSize) { for(unsigned int i = 0; i < vectorSize; i++) vector[i] = tick(); @@ -115,12 +109,6 @@ flext_stk::Output::Output(t_sample *b,int v): index(0) {} -void flext_stk::Output::tick(MY_FLOAT s) -{ - buf[index] = (t_sample)s; - if(++index >= vecsz) index = 0; -} - void flext_stk::Output::tick(const MY_FLOAT *vector,unsigned int vectorSize) { for(unsigned int i = 0; i < vectorSize; i++) tick(vector[i]); diff --git a/externals/grill/flext/source/flstk.h b/externals/grill/flext/source/flstk.h index 11d8ec6b..d6bad079 100644 --- a/externals/grill/flext/source/flstk.h +++ b/externals/grill/flext/source/flstk.h @@ -38,11 +38,16 @@ protected: public: Input(const t_sample *b,int vecsz); - MY_FLOAT lastOut() const { return (MY_FLOAT)buf[index]; } - MY_FLOAT tick(); + inline MY_FLOAT lastOut() const { return (MY_FLOAT)buf[index]; } + + inline MY_FLOAT tick() { + if(++index >= vecsz) index = 0; + return lastOut(); + } + MY_FLOAT *tick(MY_FLOAT *vector,unsigned int vectorSize); - void SetBuf(const t_sample *b) { buf = b; } + inline void SetBuf(const t_sample *b) { buf = b; } private: const t_sample *buf; @@ -56,10 +61,14 @@ protected: public: Output(t_sample *b,int vecsz); - void tick(MY_FLOAT sample); + inline void tick(MY_FLOAT s) { + buf[index] = (t_sample)s; + if(++index >= vecsz) index = 0; + } + void tick(const MY_FLOAT *vector,unsigned int vectorSize); - void SetBuf(t_sample *b) { buf = b; } + inline void SetBuf(t_sample *b) { buf = b; } private: t_sample *buf; diff --git a/externals/grill/flext/source/flsupport.cpp b/externals/grill/flext/source/flsupport.cpp index f3309ab0..115e0ee6 100644 --- a/externals/grill/flext/source/flsupport.cpp +++ b/externals/grill/flext/source/flsupport.cpp @@ -1,156 +1,157 @@ -/* - -flext - C++ layer for Max/MSP and pd (pure data) externals - -Copyright (c) 2001-2003 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. - -*/ - -/*! \file flsupport.cpp - \brief flext support functions and classes. -*/ - -#include "flext.h" - -const t_symbol *flext::sym_float = NULL; -const t_symbol *flext::sym_symbol = NULL; -const t_symbol *flext::sym_bang = NULL; -const t_symbol *flext::sym_list = NULL; -const t_symbol *flext::sym_pointer = NULL; -const t_symbol *flext::sym_int = NULL; - -#if FLEXT_SYS != FLEXT_SYS_JMAX -const t_symbol *flext::sym_anything = NULL; -#endif - -#if FLEXT_SYS == FLEXT_SYS_PD -const t_symbol *flext::sym_signal = NULL; -#endif - -void flext::Setup() -{ -#if FLEXT_SYS == FLEXT_SYS_PD - sym_anything = &s_anything; - sym_pointer = &s_pointer; - sym_float = &s_float; - sym_symbol = &s_symbol; - sym_bang = &s_bang; - sym_list = &s_list; - sym_signal = &s_signal; -#elif FLEXT_SYS == FLEXT_SYS_MAX - sym_int = gensym("int"); - sym_float = gensym("float"); - sym_symbol = gensym("symbol"); - sym_bang = gensym("bang"); - sym_list = gensym("list"); - sym_anything = gensym("anything"); -#elif FLEXT_SYS == FLEXT_SYS_JMAX - sym_int = fts_s_int; - sym_float = fts_s_float; - sym_symbol = fts_s_symbol; - sym_bang = fts_s_bang; - sym_list = fts_s_list; - sym_pointer = fts_s_pointer; -#else -#endif -} - - -///////////////////////////////////////////////////////// -// overloaded new/delete memory allocation methods -// -///////////////////////////////////////////////////////// - -void *flext::operator new(size_t bytes) -{ - bytes += sizeof(size_t); -#if FLEXT_SYS == FLEXT_SYS_JMAX - char *blk = (char *)::fts_malloc(bytes); -#else - char *blk = (char *)::getbytes(bytes); -#endif - *(size_t *)blk = bytes; - return blk+sizeof(size_t); -} - -void flext::operator delete(void *blk) -{ - char *ori = (char *)blk-sizeof(size_t); -#if FLEXT_SYS == FLEXT_SYS_JMAX - fts_free(ori); -#else - size_t bytes = *(size_t *)ori; - ::freebytes(ori,bytes); -#endif -} - -void *flext::NewAligned(size_t bytes,int bitalign) -{ - const size_t ovh = sizeof(size_t)+sizeof(char *); - const unsigned long alignovh = bitalign/8-1; - bytes += ovh+alignovh; -#if FLEXT_SYS == FLEXT_SYS_JMAX - char *blk = (char *)::fts_malloc(bytes); -#else - char *blk = (char *)::getbytes(bytes); -#endif - char *ablk = reinterpret_cast((reinterpret_cast(blk)+ovh+alignovh) & ~alignovh); - *(char **)(ablk-sizeof(size_t)-sizeof(char *)) = blk; - *(size_t *)(ablk-sizeof(size_t)) = bytes; - return ablk; -} - -void flext::FreeAligned(void *blk) -{ - char *ori = *(char **)((char *)blk-sizeof(size_t)-sizeof(char *)); - -#if FLEXT_SYS == FLEXT_SYS_JMAX - fts_free(ori); -#else - size_t bytes = *(size_t *)((char *)blk-sizeof(size_t)); - ::freebytes(ori,bytes); -#endif -} - -// ------------------------------------------ - -//! \todo there is probably also a shortcut for Max and jMax -void flext::GetAString(const t_atom &a,char *buf,int szbuf) -{ -#if FLEXT_SYS == FLEXT_SYS_PD - atom_string(const_cast(&a),buf,szbuf); -#else - if(IsSymbol(a)) sprintf(buf,GetString(a)); - else if(IsFloat(a)) sprintf(buf,"%f",GetFloat(a)); - else if(IsInt(a)) sprintf(buf,"%i",GetInt(a)); -#endif -} - -unsigned long flext::AtomHash(const t_atom &a) -{ -#if FLEXT_SYS == FLEXT_SYS_MAX || FLEXT_SYS == FLEXT_SYS_PD - return ((unsigned long)a.a_type<<28)^*(unsigned long *)&a.a_w; -#else -#error Not implemented -#endif -} - -unsigned int flext::FoldBits(unsigned long h,int bits) -{ - if(!bits) return 0; - const int hmax = (1<>i)&hmax; - return ret; -} - -int flext::Int2Bits(unsigned long n) -{ - int b; - for(b = 0; n; ++b) n >>= 1; - return b; -} - +/* + +flext - C++ layer for Max/MSP and pd (pure data) externals + +Copyright (c) 2001-2003 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. + +*/ + +/*! \file flsupport.cpp + \brief flext support functions and classes. +*/ + +#include "flext.h" + +const t_symbol *flext::sym_float = NULL; +const t_symbol *flext::sym_symbol = NULL; +const t_symbol *flext::sym_bang = NULL; +const t_symbol *flext::sym_list = NULL; +const t_symbol *flext::sym_pointer = NULL; +const t_symbol *flext::sym_int = NULL; + +#if FLEXT_SYS != FLEXT_SYS_JMAX +const t_symbol *flext::sym_anything = NULL; +#endif + +#if FLEXT_SYS == FLEXT_SYS_PD +const t_symbol *flext::sym_signal = NULL; +#endif + +void flext::Setup() +{ +#if FLEXT_SYS == FLEXT_SYS_PD + sym_anything = &s_anything; + sym_pointer = &s_pointer; + sym_float = &s_float; + sym_symbol = &s_symbol; + sym_bang = &s_bang; + sym_list = &s_list; + sym_signal = &s_signal; +#elif FLEXT_SYS == FLEXT_SYS_MAX + sym_int = gensym("int"); + sym_float = gensym("float"); + sym_symbol = gensym("symbol"); + sym_bang = gensym("bang"); + sym_list = gensym("list"); + sym_anything = gensym("anything"); +#elif FLEXT_SYS == FLEXT_SYS_JMAX + sym_int = fts_s_int; + sym_float = fts_s_float; + sym_symbol = fts_s_symbol; + sym_bang = fts_s_bang; + sym_list = fts_s_list; + sym_pointer = fts_s_pointer; +#else +#endif +} + + +///////////////////////////////////////////////////////// +// overloaded new/delete memory allocation methods +// +///////////////////////////////////////////////////////// + +void *flext::operator new(size_t bytes) +{ + bytes += sizeof(size_t); +#if FLEXT_SYS == FLEXT_SYS_JMAX + char *blk = (char *)::fts_malloc(bytes); +#else + char *blk = (char *)::getbytes(bytes); +#endif + *(size_t *)blk = bytes; + return blk+sizeof(size_t); +} + +void flext::operator delete(void *blk) +{ + char *ori = (char *)blk-sizeof(size_t); +#if FLEXT_SYS == FLEXT_SYS_JMAX + fts_free(ori); +#else + size_t bytes = *(size_t *)ori; + ::freebytes(ori,bytes); +#endif +} + +void *flext::NewAligned(size_t bytes,int bitalign) +{ + const size_t ovh = sizeof(size_t)+sizeof(char *); + const unsigned long alignovh = bitalign/8-1; + bytes += ovh+alignovh; +#if FLEXT_SYS == FLEXT_SYS_JMAX + char *blk = (char *)::fts_malloc(bytes); +#else + char *blk = (char *)::getbytes(bytes); +#endif + char *ablk = reinterpret_cast((reinterpret_cast(blk)+ovh+alignovh) & ~alignovh); + *(char **)(ablk-sizeof(size_t)-sizeof(char *)) = blk; + *(size_t *)(ablk-sizeof(size_t)) = bytes; + return ablk; +} + +void flext::FreeAligned(void *blk) +{ + char *ori = *(char **)((char *)blk-sizeof(size_t)-sizeof(char *)); + +#if FLEXT_SYS == FLEXT_SYS_JMAX + fts_free(ori); +#else + size_t bytes = *(size_t *)((char *)blk-sizeof(size_t)); + ::freebytes(ori,bytes); +#endif +} + +// ------------------------------------------ + +//! \todo there is probably also a shortcut for Max and jMax +void flext::GetAString(const t_atom &a,char *buf,int szbuf) +{ +#if FLEXT_SYS == FLEXT_SYS_PD + atom_string(const_cast(&a),buf,szbuf); +#else + if(IsSymbol(a)) snprintf(buf,szbuf,GetString(a)); + else if(IsFloat(a)) snprintf(buf,szbuf,"%f",GetFloat(a)); + else if(IsInt(a)) snprintf(buf,szbuf,"%i",GetInt(a)); + else strncpy(buf,"",szbuf); +#endif +} + +unsigned long flext::AtomHash(const t_atom &a) +{ +#if FLEXT_SYS == FLEXT_SYS_MAX || FLEXT_SYS == FLEXT_SYS_PD + return ((unsigned long)a.a_type<<28)^*(unsigned long *)&a.a_w; +#else +#error Not implemented +#endif +} + +unsigned int flext::FoldBits(unsigned long h,int bits) +{ + if(!bits) return 0; + const int hmax = (1<>i)&hmax; + return ret; +} + +int flext::Int2Bits(unsigned long n) +{ + int b; + for(b = 0; n; ++b) n >>= 1; + return b; +} + diff --git a/externals/grill/flext/source/flsupport.h b/externals/grill/flext/source/flsupport.h index 497351d2..8202922c 100644 --- a/externals/grill/flext/source/flsupport.h +++ b/externals/grill/flext/source/flsupport.h @@ -1,839 +1,839 @@ -/* - -flext - C++ layer for Max/MSP and pd (pure data) externals - -Copyright (c) 2001-2003 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. - -*/ - -/*! \file flsupport.h - \brief flext support functions and classes -*/ - -#ifndef __FLSUPPORT_H -#define __FLSUPPORT_H - -#include "flstdc.h" -#include - -class FLEXT_SHARE flext_base; - -/*! \brief Flext support class - A number of methods (most are static functions) are defined here for convenience. - This class doesn't define any data members, hence it can be inherited to all - classes (not only PD objects) to profit from the cross-platform functionality. - Examples are the overloaded memory allocation, atom and atom list functions, - thread functions and classes, the sample buffer class and others. -*/ -class FLEXT_SHARE flext { - - /*! \defgroup FLEXT_SUPPORT Flext support class - @{ - */ -public: - -// --- console output ----------------------------------------------- - -#if FLEXT_SYS == FLEXT_SYS_JMAX - //! post message to console - static void post(const char *s,...); - //! post error message to console - static void error(const char *s,...); -#endif - -// --- memory ------------------------------------------------------- - - /*! \defgroup FLEXT_S_MEMORY Memory allocation functions - @{ - */ - - /*! Overloaded new memory allocation method - \warning Max/MSP (or MacOS) allows only 16K in overdrive mode! - */ - void *operator new(size_t bytes); - //! Overloaded delete method - void operator delete(void *blk); - - #ifndef __MRC__ // doesn't allow new[] overloading?! - void *operator new[](size_t bytes) { return operator new(bytes); } - void operator delete[](void *blk) { operator delete(blk); } - #endif - - //! Get an aligned memory block - static void *NewAligned(size_t bytes,int bitalign = 128); - //! Free an aligned memory block - static void FreeAligned(void *blk); - - //! @} FLEXT_S_MEMORY - -// --- buffer/array stuff ----------------------------------------- - - /*! \defgroup FLEXT_S_BUFFER Buffer handling - @{ - */ - -// not for Jmax at the moment -#if FLEXT_SYS != FLEXT_SYS_JMAX - - //! Class for platform independent buffer handling - class FLEXT_SHARE buffer - { - public: - /*! \brief Construct buffer. - \param s: symbol name, can be NULL - \param delayed = true: only sets name, needs another Set(NULL) to really initialize the buffer - \remark As externals can be created prior to the buffer objects they are pointing to, initialization should be done at loadbang! - */ - buffer(const t_symbol *s = NULL,bool delayed = false); - - //! Destroy buffer - ~buffer(); - - /*! \brief Check if the data is valid - */ - bool Ok() const { return sym != NULL && data != NULL; } - - /*! \brief Check if buffer is valid - */ - bool Valid() const; - - /*! \brief Check and update if the buffer has been changed (e.g. resized) - */ - bool Update(); - - /*! \brief Set to specified buffer. - \param nameonly: if true sets name only, but doesn't look at buffer actually - */ - int Set(const t_symbol *s = NULL,bool nameonly = false); - - /*! \brief Declare buffer content as dirty. - \param refr: if true forces immediate graphics refresh - */ - void Dirty(bool refr = false); - - //! Get symbol of buffer - t_symbol *Symbol() const { return const_cast(sym); } - - //! Get literal name of buffer - const char *Name() const { return sym?GetString(sym):""; } - - /*! \brief Get pointer to buffer, channel and frame count. - \remark Channels are interleaved - */ - t_sample *Data() { return data; } - - //! Get channel count - int Channels() const { return chns; } - //! Get frame count - int Frames() const { return frames; } - //! Set frame count - void Frames(int fr,bool keep = false); - - //! Graphic auto refresh interval - void SetRefrIntv(float intv); - - protected: - const t_symbol *sym; - t_sample *data; - int chns,frames; -#if FLEXT_SYS == FLEXT_SYS_PD - t_garray *arr; - float interval; - bool isdirty,ticking; - t_clock *tick; - - private: - static void cb_tick(buffer *b); -#endif - }; - -#endif // jmax - -//! @} FLEXT_S_BUFFER - -// --- utilities -------------------------------------------------- - - /*! \defgroup FLEXT_S_UTIL Utility functions - @{ - */ - - //! Copy an atom - static void CopyAtom(t_atom *dst,const t_atom *src) { *dst = *src; } - - //! Print an atom - static void PrintAtom(const t_atom &a,char *buf); - //! Scan an atom - static bool ScanAtom(t_atom &a,const char *buf); - - //! Copy a list of atoms - static t_atom *CopyList(int argc,const t_atom *argv); - //! Copy a memory region - static void CopyMem(void *dst,const void *src,int bytes); - static void CopySamples(t_sample *dst,const t_sample *src,int cnt); - //! Set a memory region - static void ZeroMem(void *dst,int bytes); - static void SetSamples(t_sample *dst,int cnt,t_sample s); - static void ZeroSamples(t_sample *dst,int cnt) { SetSamples(dst,cnt,0); } - - //! Sleep for an amount of time - static void Sleep(double s); - - - //! Get a 32 bit hash value frm an atom - static unsigned long AtomHash(const t_atom &a); - - /*! \brief Fold value to a number of bits - \remark Good for hash tables - */ - static unsigned int FoldBits(unsigned long h,int bits); - - //! \brief How many bits are necessary to represent n - static int Int2Bits(unsigned long n); - -//! @} FLEXT_S_UTIL - -// --- various symbols -------------------------------------------- - - /*! \defgroup FLEXT_S_ATOM Atom/list handling - @{ - */ - - //! Symbol constant for "float" - static const t_symbol *sym_float; - //! Symbol constant for "symbol" - static const t_symbol *sym_symbol; - //! Symbol constant for "bang" - static const t_symbol *sym_bang; - //! Symbol constant for "list" - static const t_symbol *sym_list; - //! Symbol constant for "anything" - static const t_symbol *sym_anything; - - /*! \brief Symbol constant for "int" - \note Only the Max/MSP system has this defined as an internal type - */ - static const t_symbol *sym_int; - - /*! Symbol constant for "pointer" - \note Only PD has this defined as an internal type - */ - static const t_symbol *sym_pointer; - -#if FLEXT_SYS == FLEXT_SYS_PD - /*! \brief Symbol constant for "signal" - \note PD only - */ - static const t_symbol *sym_signal; -#endif - -#if FLEXT_SYS == FLEXT_SYS_JMAX - //! Make a symbol from a string - static const t_symbol *MakeSymbol(const char *s) { return ::fts_new_symbol(s); } - //! Get symbol string - static const char *GetString(const t_symbol *s); // ** TODO ** -#else - //! Make a symbol from a string - static const t_symbol *MakeSymbol(const char *s) { return ::gensym(const_cast(s)); } - //! Get symbol string - static const char *GetString(const t_symbol *s) { return s->s_name; } -#endif - //! Check for symbol and get string - static const char *GetAString(const t_symbol *s,const char *def = "") { return s?GetString(s):def; } - -// --- atom stuff ---------------------------------------- - - //! Set atom from another atom - static void SetAtom(t_atom &a,const t_atom &b) { CopyAtom(&a,&b); } - -#if FLEXT_SYS == FLEXT_SYS_JMAX - //! Set atom from another atom - static int GetType(const t_atom &a); // ** TODO ** - - //! Check whether the atom is nothing - static bool IsNothing(const t_atom &a) { return fts_is_a(&a,fts_void_class); } - //! Set the atom to represent nothing - static void SetNothing(t_atom &a) { fts_set_void(&a); } - - //! Check whether the atom is a float - static bool IsFloat(const t_atom &a) { return fts_is_a(&a,fts_float_class); } -#else - //! Set atom from another atom - static int GetType(const t_atom &a) { return a.a_type; } - - //! Check whether the atom is nothing - static bool IsNothing(const t_atom &a) { return a.a_type == A_NULL; } - //! Set the atom to represent nothing - static void SetNothing(t_atom &a) { a.a_type = A_NULL; } - - //! Check whether the atom is a float - static bool IsFloat(const t_atom &a) { return a.a_type == A_FLOAT; } -#endif - - //! Check whether the atom can be represented as a float - static bool CanbeFloat(const t_atom &a) { return IsFloat(a) || IsInt(a); } - -#if FLEXT_SYS == FLEXT_SYS_JMAX - //! Access the float value (without type check) - static float GetFloat(const t_atom &a) { return fts_get_float(&a); } - //! Set the atom to represent a float - static void SetFloat(t_atom &a,float v) { fts_set_float(&a,v); } - - //! Check whether the atom is a symbol - static bool IsSymbol(const t_atom &a) { return fts_is_a(&a,fts_symbol_class); } -#else - //! Access the float value (without type check) - static float GetFloat(const t_atom &a) { return a.a_w.w_float; } - //! Set the atom to represent a float - static void SetFloat(t_atom &a,float v) { a.a_type = A_FLOAT; a.a_w.w_float = v; } - - //! Check whether the atom is a symbol - static bool IsSymbol(const t_atom &a) { return a.a_type == A_SYMBOL; } -#endif - -#if FLEXT_SYS == FLEXT_SYS_PD - //! Access the symbol value (without type check) - static t_symbol *GetSymbol(const t_atom &a) { return a.a_w.w_symbol; } - //! Set the atom to represent a symbol - static void SetSymbol(t_atom &a,const t_symbol *s) { a.a_type = A_SYMBOL; a.a_w.w_symbol = const_cast(s); } -#elif FLEXT_SYS == FLEXT_SYS_MAX - //! Access the symbol value (without type check) - static t_symbol *GetSymbol(const t_atom &a) { return a.a_w.w_sym; } - //! Set the atom to represent a symbol - static void SetSymbol(t_atom &a,const t_symbol *s) { a.a_type = A_SYMBOL; a.a_w.w_sym = const_cast(s); } -#elif FLEXT_SYS == FLEXT_SYS_JMAX - //! Access the symbol value (without type check) - static t_symbol *GetSymbol(const t_atom &a); // ** TODO ** - //! Set the atom to represent a symbol - static void SetSymbol(t_atom &a,const t_symbol *s) { fts_set_symbol(&a,s); } -#else -#error -#endif - //! Check for a symbol and get its value - static t_symbol *GetASymbol(const t_atom &a,t_symbol *def = NULL) { return IsSymbol(a)?GetSymbol(a):def; } // NULL or empty symbol? - - //! Check whether the atom is a string - static bool IsString(const t_atom &a) { return IsSymbol(a); } - //! Access the string value (without type check) - static const char *GetString(const t_atom &a) { t_symbol *s = GetSymbol(a); return s?GetString(s):NULL; } - //! Check for a string and get its value - static void GetAString(const t_atom &a,char *buf,int szbuf); - //! Set the atom to represent a string - static void SetString(t_atom &a,const char *c) { SetSymbol(a,MakeSymbol(c)); } - - //! Check whether the atom can be represented as an integer - static bool CanbeInt(const t_atom &a) { return IsFloat(a) || IsInt(a); } - - //! Set the atom to represent a boolean - static void SetBool(t_atom &a,bool v) { SetInt(a,v?1:0); } - //! Check whether the atom can be represented as a boolean - static bool CanbeBool(const t_atom &a) { return CanbeInt(a); } - //! Check for an boolean and get its value - static bool GetABool(const t_atom &a) { return GetAInt(a) != 0; } - -#if FLEXT_SYS == FLEXT_SYS_PD - //! Check for a float and get its value - static float GetAFloat(const t_atom &a,float def = 0) { return IsFloat(a)?GetFloat(a):def; } - - //! Check whether the atom is an integer - static bool IsInt(const t_atom &) { return false; } - //! Access the integer value (without type check) - static int GetInt(const t_atom &a) { return (int)GetFloat(a); } - //! Check for an integer and get its value - static int GetAInt(const t_atom &a,int def = 0) { return (int)GetAFloat(a,(float)def); } - //! Set the atom to represent a integer (depending on the system) - static void SetInt(t_atom &a,int v) { a.a_type = A_FLOAT; a.a_w.w_float = (float)v; } - - //! Check whether the atom strictly is a pointer - static bool IsPointer(const t_atom &a) { return a.a_type == A_POINTER; } - //! Check whether the atom can be a pointer - static bool CanbePointer(const t_atom &a) { return IsPointer(a); } - //! Access the pointer value (without type check) - static void *GetPointer(const t_atom &a) { return a.a_w.w_gpointer; } - //! Check for a pointer and get its value - static void *GetAPointer(const t_atom &a,void *def = NULL) { return IsPointer(a)?GetPointer(a):def; } - //! Set the atom to represent a pointer - static void SetPointer(t_atom &a,void *p) { a.a_type = A_POINTER; a.a_w.w_gpointer = (t_gpointer *)p; } - -#elif FLEXT_SYS == FLEXT_SYS_MAX - //! Check for a float and get its value - static float GetAFloat(const t_atom &a,float def = 0) { return IsFloat(a)?GetFloat(a):(IsInt(a)?GetInt(a):def); } - - //! Check whether the atom is an int - static bool IsInt(const t_atom &a) { return a.a_type == A_INT; } - //! Access the integer value (without type check) - static int GetInt(const t_atom &a) { return a.a_w.w_long; } - //! Check for an integer and get its value - static int GetAInt(const t_atom &a,int def = 0) { return IsInt(a)?GetInt(a):(IsFloat(a)?(int)GetFloat(a):def); } - //! Set the atom to represent an integer - static void SetInt(t_atom &a,int v) { a.a_type = A_INT; a.a_w.w_long = v; } - - //! Check whether the atom strictly is a pointer - static bool IsPointer(const t_atom &) { return false; } - //! Check whether the atom can be a pointer - static bool CanbePointer(const t_atom &a) { return IsInt(a); } - //! Access the pointer value (without type check) - static void *GetPointer(const t_atom &) { return NULL; } - //! Check for a pointer and get its value - static void *GetAPointer(const t_atom &a,void *def = NULL) { return IsInt(a)?(void *)GetInt(a):def; } - //! Set the atom to represent a pointer - static void SetPointer(t_atom &a,void *p) { SetInt(a,(int)p); } -#elif FLEXT_SYS == FLEXT_SYS_JMAX - //! Check for a float and get its value - static float GetAFloat(const t_atom &a,float def = 0) { return IsFloat(a)?GetFloat(a):(IsInt(a)?GetInt(a):def); } - - //! Check whether the atom is an int - static bool IsInt(const t_atom &a) { return fts_is_a(&a,fts_int_class); } - //! Access the integer value (without type check) - static int GetInt(const t_atom &a) { return fts_get_int(&a); } - //! Check for an integer and get its value - static int GetAInt(const t_atom &a,int def = 0) { return IsInt(a)?GetInt(a):(IsFloat(a)?(int)GetFloat(a):def); } - //! Set the atom to represent an integer - static void SetInt(t_atom &a,int v) { fts_set_int(&a,v); } - - //! Check whether the atom strictly is a pointer - static bool IsPointer(const t_atom &a) { return fts_is_a(&a,fts_pointer_class); } - //! Check whether the atom can be a pointer - static bool CanbePointer(const t_atom &a) { return IsPointer(a); } - //! Access the pointer value (without type check) - static void *GetPointer(const t_atom &a) { return fts_get_pointer(&a); } - //! Check for a pointer and get its value - static void *GetAPointer(const t_atom &a,void *def = NULL) { return IsPointer(a)?GetPointer(a):def; } - //! Set the atom to represent a pointer - static void SetPointer(t_atom &a,void *p) { fts_set_pointer(&a,p); } -#else -#error "Platform not supported" -#endif - -// --- atom list stuff ------------------------------------------- - - //! Class representing a list of atoms - class FLEXT_SHARE AtomList - { - public: - //! Construct list - AtomList(int argc = 0,const t_atom *argv = NULL); - //! Construct list - AtomList(const AtomList &a); - //! Destroy list - ~AtomList(); - - //! Clear list - AtomList &Clear() { return operator()(); } - - //! Set list - AtomList &Set(int argc,const t_atom *argv,int offs = 0,bool resize = false); - //! Get list - int Get(t_atom *argv,int mxsz = -1) const; - - //! Set list - AtomList &operator()(int argc = 0,const t_atom *argv = NULL) { return Set(argc,argv,0,true); } - //! Set list by another AtomList - AtomList &operator =(const AtomList &a) { return operator()(a.Count(),a.Atoms()); } - - //! Get number of atoms in the list - int Count() const { return cnt; } - //! Get a reference to an indexed atom - t_atom &operator [](int ix) { return lst[ix]; } - //! Get a reference to an indexed atom - const t_atom &operator [](int ix) const { return lst[ix]; } - - //! Get a pointer to the list of atoms - t_atom *Atoms() { return lst; } - //! Get a pointer to the list of atoms - const t_atom *Atoms() const { return lst; } - - //! Append an atom to the list - AtomList &Append(const t_atom &a); - //! Append an atom list to the list - AtomList &Append(int argc,const t_atom *argv = NULL); - //! Append an atom list to the list - AtomList &Append(const AtomList &a) { return Append(a.Count(),a.Atoms()); } - //! Prepend an atom to the list - AtomList &Prepend(const t_atom &a); - //! Prepend an atom list to the list - AtomList &Prepend(int argc,const t_atom *argv = NULL); - //! Prepend an atom list to the list - AtomList &Prepend(const AtomList &a) { return Prepend(a.Count(),a.Atoms()); } - - //! Get a part of the list - AtomList GetPart(int offs,int len) const; - //! Set to a part of the list - AtomList &Part(int offs,int len) { return (*this = GetPart(offs,len)); } - - protected: - int cnt; - t_atom *lst; - }; - - - //! Class representing an "anything" - class FLEXT_SHARE AtomAnything: - public AtomList - { - public: -#if FLEXT_SYS != FLEXT_SYS_JMAX - //! Construct anything - AtomAnything(const t_symbol *h = NULL,int argc = 0,const t_atom *argv = NULL); -#endif - //! Construct anything - AtomAnything(const char *h,int argc = 0,const t_atom *argv = NULL); - //! Construct anything - AtomAnything(const AtomAnything &a); - - //! Clear anything - AtomAnything &Clear() { return operator()(); } - - //! Get header symbol of anything - const t_symbol *Header() const { return hdr; } - - //! Set header symbol of anything - void Header(const t_symbol *h) { hdr = h; } - - //! Set anything - AtomAnything &operator()(const t_symbol *h = NULL,int argc = 0,const t_atom *argv = NULL) - { - hdr = h; AtomList::operator()(argc,argv); - return *this; - } - - //! Set list by another AtomAnything - AtomAnything &operator =(const AtomAnything &a) { return operator()(a.Header(),a.Count(),a.Atoms()); } - - protected: - const t_symbol *hdr; - }; - -//! @} FLEXT_S_ATOM - - -// --- clock stuff ------------------------------------------------ - - - /*! \defgroup FLEXT_S_CLOCK Flext clock functions - - At the moment there are none - - @{ - */ - -//! @} - - -// --- thread stuff ----------------------------------------------- - -#ifdef FLEXT_THREADS - /*! \defgroup FLEXT_S_THREAD Flext thread handling - @{ - */ - - //! thread type -#if FLEXT_THREADS == FLEXT_THR_MP - typedef MPTaskID thrid_t; -#elif FLEXT_THREADS == FLEXT_THR_POSIX - typedef pthread_t thrid_t; -#else -#error -#endif - - /*! \brief Get current thread id - */ - static thrid_t GetThreadId() { -#if FLEXT_THREADS == FLEXT_THR_POSIX - return pthread_self(); -#elif FLEXT_THREADS == FLEXT_THR_MP - return MPCurrentTaskID(); -#else -#error -#endif - } - - /*! \brief Get system thread id - */ - static thrid_t GetSysThreadId() { return thrid; } - - //! Check if current thread is the realtime system's thread - static bool IsThread(thrid_t t,thrid_t ref = GetThreadId()) { -#if FLEXT_THREADS == FLEXT_THR_POSIX - return pthread_equal(ref,t) != 0; -#else - return ref == t; -#endif - } - - //! Check if current thread is the realtime system's thread - static bool IsSystemThread() { return IsThread(GetSysThreadId()); } - - - /*! \brief Thread parameters - \internal - */ - class thr_params - { - public: - thr_params(int n = 1); - ~thr_params(); - - void set_any(const t_symbol *s,int argc,const t_atom *argv); - void set_list(int argc,const t_atom *argv); - - flext_base *cl; - union _data { - bool _bool; - float _float; - int _int; - t_symptr _t_symptr; - struct { AtomAnything *args; } _any; - struct { AtomList *args; } _list; - struct { void *data; } _ext; - } *var; - }; - - /*! \brief This represents an entry to the list of active method threads - \internal - */ - class thr_entry - { - public: - thr_entry(void (*m)(thr_params *),thr_params *p,thrid_t id = GetThreadId()); - - //! \brief Check if this class represents the current thread - bool Is(thrid_t id = GetThreadId()) const { return IsThread(thrid,id); } - - flext_base *This() const { return th; } - thrid_t Id() const { return thrid; } - - flext_base *th; - void (*meth)(thr_params *); - thr_params *params; - thrid_t thrid; - bool active,shouldexit; -#if FLEXT_THREADS == FLEXT_THR_MP - int weight; -#endif - thr_entry *nxt; - }; - -protected: - - static thrid_t thrhelpid; - static bool StartHelper(); - static bool StopHelper(); - static void ThrHelper(void *); - - //! system's thread id - static thrid_t thrid; // the system thread - -public: - - /*! \brief Yield to other threads - \remark A call to this is only needed for systems with cooperative multitasking like MacOS<=9 - */ - static void ThrYield() { -#if FLEXT_THREADS == FLEXT_THR_POSIX - sched_yield(); -#elif FLEXT_THREADS == FLEXT_THR_MP - MPYield(); -#else -#error -#endif - } - - /*! \brief Query whether task is preemptive - */ - static bool IsThreadPreemptive(thrid_t t = GetThreadId()) { -#if FLEXT_THREADS == FLEXT_THR_POSIX || FLEXT_THREADS == FLEXT_THR_WIN32 - return true; -#elif FLEXT_THREADS == FLEXT_THR_MP - return MPTaskIsPreemptive(t); -#else -#error -#endif - } - - - /*! \brief Increase/Decrease priority of a thread - */ - static bool RelPriority(int dp,thrid_t ref = GetSysThreadId(),thrid_t thr = GetThreadId()); - - /*! \brief Get priority of a thread - */ - static int GetPriority(thrid_t thr = GetThreadId()); - - /*! \brief Set priority of a thread - */ - static bool SetPriority(int p,thrid_t thr = GetThreadId()); - - /*! \brief Thread mutex - \sa pthreads documentation - */ - class FLEXT_SHARE ThrMutex -#if FLEXT_THREADS == FLEXT_THR_POSIX - { - public: - //! Construct thread mutex - ThrMutex() /*: cnt(0)*/ { pthread_mutex_init(&mutex,NULL); } - //! Destroy thread mutex - ~ThrMutex() { pthread_mutex_destroy(&mutex); } - - //! Lock thread mutex - bool Lock() { /*cnt = 1;*/ return pthread_mutex_lock(&mutex) == 0; } - //! Lock thread mutex - bool WaitForLock(float tm) { /*cnt = 1;*/ return pthread_mutex_lock(&mutex) == 0; } - //! Try to lock, but don't wait - bool TryLock() { return pthread_mutex_trylock(&mutex) == 0; } - //! Unlock thread mutex - bool Unlock() { /*cnt = 0;*/ return pthread_mutex_unlock(&mutex) == 0; } -/* - //! Lock thread mutex (increase lock count by one) - void Push() { if(!cnt++) Lock(); } - //! Unlock thread mutex if lock count reaches zero - void Pop() { if(!--cnt) Unlock(); } -*/ - protected: - pthread_mutex_t mutex; -// int cnt; - }; -#elif FLEXT_THREADS == FLEXT_THR_MP - { - public: - //! Construct thread mutex - ThrMutex() /*: cnt(0)*/ { MPCreateCriticalRegion(&crit); } - //! Destroy thread mutex - ~ThrMutex() { MPDeleteCriticalRegion(crit); } - - //! Lock thread mutex - bool Lock() { /*cnt = 1;*/ return MPEnterCriticalRegion(crit,kDurationForever) == noErr; } - //! Wait to lock thread mutex - bool WaitForLock(float tm) { /*cnt = 1;*/ return MPEnterCriticalRegion(crit,tm*kDurationMicrosecond*1.e6) == noErr; } - //! Try to lock, but don't wait - bool TryLock() { return MPEnterCriticalRegion(crit,kDurationImmediate) == noErr; } - //! Unlock thread mutex - bool Unlock() { /*cnt = 0;*/ return MPExitCriticalRegion(crit) == noErr; } - - protected: - MPCriticalRegionID crit; - }; -#else -#error "Not implemented" -#endif - - /*! \brief Thread conditional - \sa pthreads documentation - */ - class FLEXT_SHARE ThrCond -#if FLEXT_THREADS == FLEXT_THR_POSIX - :public ThrMutex - { - public: - //! Construct thread conditional - ThrCond() { pthread_cond_init(&cond,NULL); } - //! Destroy thread conditional - ~ThrCond() { pthread_cond_destroy(&cond); } - - //! Wait for condition - bool Wait() { - Lock(); - bool ret = pthread_cond_wait(&cond,&mutex) == 0; - Unlock(); - return ret; - } - - /*! \brief Wait for condition (for a certain time) - \param ftime Wait time in seconds - \ret 0 = signalled, 1 = timed out - \remark Depending on the implementation ftime may not be fractional. - \remark So if ftime = 0 this may suck away your cpu if used in a signalled loop. - */ - bool TimedWait(float ftime) - { - timespec tm; -#if 0 // find out when the following is defined - clock_gettime(CLOCK_REALTIME,tm); - tm.tv_nsec += (long)((ftime-(long)ftime)*1.e9); - long nns = tm.tv_nsec%1000000000; - tm.tv_sec += (long)ftime+(tm.tv_nsec-nns)/1000000000; - tm.tv_nsec = nns; -#else - tm.tv_sec = time(NULL)+(long)ftime; - tm.tv_nsec = 0; -#endif - Lock(); - bool ret = pthread_cond_timedwait(&cond,&mutex,&tm) == 0; - Unlock(); - return ret; - } - - //! Signal condition - bool Signal() - { - Lock(); - bool ret = pthread_cond_signal(&cond) == 0; - Unlock(); - return ret; - } - //! Broadcast condition -// int Broadcast() { return pthread_cond_broadcast(&cond); } - protected: - pthread_cond_t cond; - }; -#elif FLEXT_THREADS == FLEXT_THR_MP - { - public: - //! Construct thread conditional - ThrCond() { MPCreateEvent(&ev); } - //! Destroy thread conditional - ~ThrCond() { MPDeleteEvent(ev); } - - //! Wait for condition - bool Wait() { return MPWaitForEvent(ev,NULL,kDurationForever) == noErr; } - - /*! \brief Wait for condition (for a certain time) - \param time Wait time in seconds - */ - bool TimedWait(float tm) { return MPWaitForEvent(ev,NULL,tm*kDurationMicrosecond*1.e6) == noErr; } - - //! Signal condition - bool Signal() { return MPSetEvent(ev,1) == noErr; } // one bit needs to be set at least - //! Broadcast condition -// int Broadcast() { return pthread_cond_broadcast(&cond); } - protected: - MPEventID ev; - }; -#else -#error "Not implemented" -#endif - - /*! \brief Add current thread to list of active threads - \return true on success - \internal - */ - static bool PushThread(); - - /*! \brief Remove current thread from list of active threads - \internal - */ - static void PopThread(); - - /*! \brief Launch a thread - \remark thr_params *p may be NULL if not needed - */ - static bool LaunchThread(void (*meth)(thr_params *p),thr_params *p); - -//! @} FLEXT_S_THREAD - -#endif // FLEXT_THREADS - -//! @} - -protected: -#ifdef __MRC__ - friend class flext_obj; -#endif - static void Setup(); - - static bool chktilde(const char *objname); -}; - -#endif +/* + +flext - C++ layer for Max/MSP and pd (pure data) externals + +Copyright (c) 2001-2003 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. + +*/ + +/*! \file flsupport.h + \brief flext support functions and classes +*/ + +#ifndef __FLSUPPORT_H +#define __FLSUPPORT_H + +#include "flstdc.h" +#include + +class FLEXT_SHARE flext_base; + +/*! \brief Flext support class + A number of methods (most are static functions) are defined here for convenience. + This class doesn't define any data members, hence it can be inherited to all + classes (not only PD objects) to profit from the cross-platform functionality. + Examples are the overloaded memory allocation, atom and atom list functions, + thread functions and classes, the sample buffer class and others. +*/ +class FLEXT_SHARE flext { + + /*! \defgroup FLEXT_SUPPORT Flext support class + @{ + */ +public: + +// --- console output ----------------------------------------------- + +#if FLEXT_SYS == FLEXT_SYS_JMAX + //! post message to console + static void post(const char *s,...); + //! post error message to console + static void error(const char *s,...); +#endif + +// --- memory ------------------------------------------------------- + + /*! \defgroup FLEXT_S_MEMORY Memory allocation functions + @{ + */ + + /*! Overloaded new memory allocation method + \warning Max/MSP (or MacOS) allows only 16K in overdrive mode! + */ + void *operator new(size_t bytes); + //! Overloaded delete method + void operator delete(void *blk); + + #ifndef __MRC__ // doesn't allow new[] overloading?! + void *operator new[](size_t bytes) { return operator new(bytes); } + void operator delete[](void *blk) { operator delete(blk); } + #endif + + //! Get an aligned memory block + static void *NewAligned(size_t bytes,int bitalign = 128); + //! Free an aligned memory block + static void FreeAligned(void *blk); + + //! @} FLEXT_S_MEMORY + +// --- buffer/array stuff ----------------------------------------- + + /*! \defgroup FLEXT_S_BUFFER Buffer handling + @{ + */ + +// not for Jmax at the moment +#if FLEXT_SYS != FLEXT_SYS_JMAX + + //! Class for platform independent buffer handling + class FLEXT_SHARE buffer + { + public: + /*! \brief Construct buffer. + \param s: symbol name, can be NULL + \param delayed = true: only sets name, needs another Set(NULL) to really initialize the buffer + \remark As externals can be created prior to the buffer objects they are pointing to, initialization should be done at loadbang! + */ + buffer(const t_symbol *s = NULL,bool delayed = false); + + //! Destroy buffer + ~buffer(); + + /*! \brief Check if the data is valid + */ + bool Ok() const { return sym != NULL && data != NULL; } + + /*! \brief Check if buffer is valid + */ + bool Valid() const; + + /*! \brief Check and update if the buffer has been changed (e.g. resized) + */ + bool Update(); + + /*! \brief Set to specified buffer. + \param nameonly: if true sets name only, but doesn't look at buffer actually + */ + int Set(const t_symbol *s = NULL,bool nameonly = false); + + /*! \brief Declare buffer content as dirty. + \param refr: if true forces immediate graphics refresh + */ + void Dirty(bool refr = false); + + //! Get symbol of buffer + t_symbol *Symbol() const { return const_cast(sym); } + + //! Get literal name of buffer + const char *Name() const { return sym?GetString(sym):""; } + + /*! \brief Get pointer to buffer, channel and frame count. + \remark Channels are interleaved + */ + t_sample *Data() { return data; } + + //! Get channel count + int Channels() const { return chns; } + //! Get frame count + int Frames() const { return frames; } + //! Set frame count + void Frames(int fr,bool keep = false); + + //! Graphic auto refresh interval + void SetRefrIntv(float intv); + + protected: + const t_symbol *sym; + t_sample *data; + int chns,frames; +#if FLEXT_SYS == FLEXT_SYS_PD + t_garray *arr; + float interval; + bool isdirty,ticking; + t_clock *tick; + + private: + static void cb_tick(buffer *b); +#endif + }; + +#endif // jmax + +//! @} FLEXT_S_BUFFER + +// --- utilities -------------------------------------------------- + + /*! \defgroup FLEXT_S_UTIL Utility functions + @{ + */ + + //! Copy an atom + static void CopyAtom(t_atom *dst,const t_atom *src) { *dst = *src; } + + //! Print an atom + static void PrintAtom(const t_atom &a,char *buf,int bufsz = 0); + //! Scan an atom + static bool ScanAtom(t_atom &a,const char *buf); + + //! Copy a list of atoms + static t_atom *CopyList(int argc,const t_atom *argv); + //! Copy a memory region + static void CopyMem(void *dst,const void *src,int bytes); + static void CopySamples(t_sample *dst,const t_sample *src,int cnt); + //! Set a memory region + static void ZeroMem(void *dst,int bytes); + static void SetSamples(t_sample *dst,int cnt,t_sample s); + static void ZeroSamples(t_sample *dst,int cnt) { SetSamples(dst,cnt,0); } + + //! Sleep for an amount of time + static void Sleep(double s); + + + //! Get a 32 bit hash value frm an atom + static unsigned long AtomHash(const t_atom &a); + + /*! \brief Fold value to a number of bits + \remark Good for hash tables + */ + static unsigned int FoldBits(unsigned long h,int bits); + + //! \brief How many bits are necessary to represent n + static int Int2Bits(unsigned long n); + +//! @} FLEXT_S_UTIL + +// --- various symbols -------------------------------------------- + + /*! \defgroup FLEXT_S_ATOM Atom/list handling + @{ + */ + + //! Symbol constant for "float" + static const t_symbol *sym_float; + //! Symbol constant for "symbol" + static const t_symbol *sym_symbol; + //! Symbol constant for "bang" + static const t_symbol *sym_bang; + //! Symbol constant for "list" + static const t_symbol *sym_list; + //! Symbol constant for "anything" + static const t_symbol *sym_anything; + + /*! \brief Symbol constant for "int" + \note Only the Max/MSP system has this defined as an internal type + */ + static const t_symbol *sym_int; + + /*! Symbol constant for "pointer" + \note Only PD has this defined as an internal type + */ + static const t_symbol *sym_pointer; + +#if FLEXT_SYS == FLEXT_SYS_PD + /*! \brief Symbol constant for "signal" + \note PD only + */ + static const t_symbol *sym_signal; +#endif + +#if FLEXT_SYS == FLEXT_SYS_JMAX + //! Make a symbol from a string + static const t_symbol *MakeSymbol(const char *s) { return ::fts_new_symbol(s); } + //! Get symbol string + static const char *GetString(const t_symbol *s); // ** TODO ** +#else + //! Make a symbol from a string + static const t_symbol *MakeSymbol(const char *s) { return ::gensym(const_cast(s)); } + //! Get symbol string + static const char *GetString(const t_symbol *s) { return s->s_name; } +#endif + //! Check for symbol and get string + static const char *GetAString(const t_symbol *s,const char *def = "") { return s?GetString(s):def; } + +// --- atom stuff ---------------------------------------- + + //! Set atom from another atom + static void SetAtom(t_atom &a,const t_atom &b) { CopyAtom(&a,&b); } + +#if FLEXT_SYS == FLEXT_SYS_JMAX + //! Set atom from another atom + static int GetType(const t_atom &a); // ** TODO ** + + //! Check whether the atom is nothing + static bool IsNothing(const t_atom &a) { return fts_is_a(&a,fts_void_class); } + //! Set the atom to represent nothing + static void SetNothing(t_atom &a) { fts_set_void(&a); } + + //! Check whether the atom is a float + static bool IsFloat(const t_atom &a) { return fts_is_a(&a,fts_float_class); } +#else + //! Set atom from another atom + static int GetType(const t_atom &a) { return a.a_type; } + + //! Check whether the atom is nothing + static bool IsNothing(const t_atom &a) { return a.a_type == A_NULL; } + //! Set the atom to represent nothing + static void SetNothing(t_atom &a) { a.a_type = A_NULL; } + + //! Check whether the atom is a float + static bool IsFloat(const t_atom &a) { return a.a_type == A_FLOAT; } +#endif + + //! Check whether the atom can be represented as a float + static bool CanbeFloat(const t_atom &a) { return IsFloat(a) || IsInt(a); } + +#if FLEXT_SYS == FLEXT_SYS_JMAX + //! Access the float value (without type check) + static float GetFloat(const t_atom &a) { return fts_get_float(&a); } + //! Set the atom to represent a float + static void SetFloat(t_atom &a,float v) { fts_set_float(&a,v); } + + //! Check whether the atom is a symbol + static bool IsSymbol(const t_atom &a) { return fts_is_a(&a,fts_symbol_class); } +#else + //! Access the float value (without type check) + static float GetFloat(const t_atom &a) { return a.a_w.w_float; } + //! Set the atom to represent a float + static void SetFloat(t_atom &a,float v) { a.a_type = A_FLOAT; a.a_w.w_float = v; } + + //! Check whether the atom is a symbol + static bool IsSymbol(const t_atom &a) { return a.a_type == A_SYMBOL; } +#endif + +#if FLEXT_SYS == FLEXT_SYS_PD + //! Access the symbol value (without type check) + static t_symbol *GetSymbol(const t_atom &a) { return a.a_w.w_symbol; } + //! Set the atom to represent a symbol + static void SetSymbol(t_atom &a,const t_symbol *s) { a.a_type = A_SYMBOL; a.a_w.w_symbol = const_cast(s); } +#elif FLEXT_SYS == FLEXT_SYS_MAX + //! Access the symbol value (without type check) + static t_symbol *GetSymbol(const t_atom &a) { return a.a_w.w_sym; } + //! Set the atom to represent a symbol + static void SetSymbol(t_atom &a,const t_symbol *s) { a.a_type = A_SYMBOL; a.a_w.w_sym = const_cast(s); } +#elif FLEXT_SYS == FLEXT_SYS_JMAX + //! Access the symbol value (without type check) + static t_symbol *GetSymbol(const t_atom &a); // ** TODO ** + //! Set the atom to represent a symbol + static void SetSymbol(t_atom &a,const t_symbol *s) { fts_set_symbol(&a,s); } +#else +#error +#endif + //! Check for a symbol and get its value + static t_symbol *GetASymbol(const t_atom &a,t_symbol *def = NULL) { return IsSymbol(a)?GetSymbol(a):def; } // NULL or empty symbol? + + //! Check whether the atom is a string + static bool IsString(const t_atom &a) { return IsSymbol(a); } + //! Access the string value (without type check) + static const char *GetString(const t_atom &a) { t_symbol *s = GetSymbol(a); return s?GetString(s):NULL; } + //! Check for a string and get its value + static void GetAString(const t_atom &a,char *buf,int szbuf); + //! Set the atom to represent a string + static void SetString(t_atom &a,const char *c) { SetSymbol(a,MakeSymbol(c)); } + + //! Check whether the atom can be represented as an integer + static bool CanbeInt(const t_atom &a) { return IsFloat(a) || IsInt(a); } + + //! Set the atom to represent a boolean + static void SetBool(t_atom &a,bool v) { SetInt(a,v?1:0); } + //! Check whether the atom can be represented as a boolean + static bool CanbeBool(const t_atom &a) { return CanbeInt(a); } + //! Check for an boolean and get its value + static bool GetABool(const t_atom &a) { return GetAInt(a) != 0; } + +#if FLEXT_SYS == FLEXT_SYS_PD + //! Check for a float and get its value + static float GetAFloat(const t_atom &a,float def = 0) { return IsFloat(a)?GetFloat(a):def; } + + //! Check whether the atom is an integer + static bool IsInt(const t_atom &) { return false; } + //! Access the integer value (without type check) + static int GetInt(const t_atom &a) { return (int)GetFloat(a); } + //! Check for an integer and get its value + static int GetAInt(const t_atom &a,int def = 0) { return (int)GetAFloat(a,(float)def); } + //! Set the atom to represent a integer (depending on the system) + static void SetInt(t_atom &a,int v) { a.a_type = A_FLOAT; a.a_w.w_float = (float)v; } + + //! Check whether the atom strictly is a pointer + static bool IsPointer(const t_atom &a) { return a.a_type == A_POINTER; } + //! Check whether the atom can be a pointer + static bool CanbePointer(const t_atom &a) { return IsPointer(a); } + //! Access the pointer value (without type check) + static void *GetPointer(const t_atom &a) { return a.a_w.w_gpointer; } + //! Check for a pointer and get its value + static void *GetAPointer(const t_atom &a,void *def = NULL) { return IsPointer(a)?GetPointer(a):def; } + //! Set the atom to represent a pointer + static void SetPointer(t_atom &a,void *p) { a.a_type = A_POINTER; a.a_w.w_gpointer = (t_gpointer *)p; } + +#elif FLEXT_SYS == FLEXT_SYS_MAX + //! Check for a float and get its value + static float GetAFloat(const t_atom &a,float def = 0) { return IsFloat(a)?GetFloat(a):(IsInt(a)?GetInt(a):def); } + + //! Check whether the atom is an int + static bool IsInt(const t_atom &a) { return a.a_type == A_INT; } + //! Access the integer value (without type check) + static int GetInt(const t_atom &a) { return a.a_w.w_long; } + //! Check for an integer and get its value + static int GetAInt(const t_atom &a,int def = 0) { return IsInt(a)?GetInt(a):(IsFloat(a)?(int)GetFloat(a):def); } + //! Set the atom to represent an integer + static void SetInt(t_atom &a,int v) { a.a_type = A_INT; a.a_w.w_long = v; } + + //! Check whether the atom strictly is a pointer + static bool IsPointer(const t_atom &) { return false; } + //! Check whether the atom can be a pointer + static bool CanbePointer(const t_atom &a) { return IsInt(a); } + //! Access the pointer value (without type check) + static void *GetPointer(const t_atom &) { return NULL; } + //! Check for a pointer and get its value + static void *GetAPointer(const t_atom &a,void *def = NULL) { return IsInt(a)?(void *)GetInt(a):def; } + //! Set the atom to represent a pointer + static void SetPointer(t_atom &a,void *p) { SetInt(a,(int)p); } +#elif FLEXT_SYS == FLEXT_SYS_JMAX + //! Check for a float and get its value + static float GetAFloat(const t_atom &a,float def = 0) { return IsFloat(a)?GetFloat(a):(IsInt(a)?GetInt(a):def); } + + //! Check whether the atom is an int + static bool IsInt(const t_atom &a) { return fts_is_a(&a,fts_int_class); } + //! Access the integer value (without type check) + static int GetInt(const t_atom &a) { return fts_get_int(&a); } + //! Check for an integer and get its value + static int GetAInt(const t_atom &a,int def = 0) { return IsInt(a)?GetInt(a):(IsFloat(a)?(int)GetFloat(a):def); } + //! Set the atom to represent an integer + static void SetInt(t_atom &a,int v) { fts_set_int(&a,v); } + + //! Check whether the atom strictly is a pointer + static bool IsPointer(const t_atom &a) { return fts_is_a(&a,fts_pointer_class); } + //! Check whether the atom can be a pointer + static bool CanbePointer(const t_atom &a) { return IsPointer(a); } + //! Access the pointer value (without type check) + static void *GetPointer(const t_atom &a) { return fts_get_pointer(&a); } + //! Check for a pointer and get its value + static void *GetAPointer(const t_atom &a,void *def = NULL) { return IsPointer(a)?GetPointer(a):def; } + //! Set the atom to represent a pointer + static void SetPointer(t_atom &a,void *p) { fts_set_pointer(&a,p); } +#else +#error "Platform not supported" +#endif + +// --- atom list stuff ------------------------------------------- + + //! Class representing a list of atoms + class FLEXT_SHARE AtomList + { + public: + //! Construct list + AtomList(int argc = 0,const t_atom *argv = NULL); + //! Construct list + AtomList(const AtomList &a); + //! Destroy list + ~AtomList(); + + //! Clear list + AtomList &Clear() { return operator()(); } + + //! Set list + AtomList &Set(int argc,const t_atom *argv,int offs = 0,bool resize = false); + //! Get list + int Get(t_atom *argv,int mxsz = -1) const; + + //! Set list + AtomList &operator()(int argc = 0,const t_atom *argv = NULL) { return Set(argc,argv,0,true); } + //! Set list by another AtomList + AtomList &operator =(const AtomList &a) { return operator()(a.Count(),a.Atoms()); } + + //! Get number of atoms in the list + int Count() const { return cnt; } + //! Get a reference to an indexed atom + t_atom &operator [](int ix) { return lst[ix]; } + //! Get a reference to an indexed atom + const t_atom &operator [](int ix) const { return lst[ix]; } + + //! Get a pointer to the list of atoms + t_atom *Atoms() { return lst; } + //! Get a pointer to the list of atoms + const t_atom *Atoms() const { return lst; } + + //! Append an atom to the list + AtomList &Append(const t_atom &a); + //! Append an atom list to the list + AtomList &Append(int argc,const t_atom *argv = NULL); + //! Append an atom list to the list + AtomList &Append(const AtomList &a) { return Append(a.Count(),a.Atoms()); } + //! Prepend an atom to the list + AtomList &Prepend(const t_atom &a); + //! Prepend an atom list to the list + AtomList &Prepend(int argc,const t_atom *argv = NULL); + //! Prepend an atom list to the list + AtomList &Prepend(const AtomList &a) { return Prepend(a.Count(),a.Atoms()); } + + //! Get a part of the list + AtomList GetPart(int offs,int len) const; + //! Set to a part of the list + AtomList &Part(int offs,int len) { return (*this = GetPart(offs,len)); } + + protected: + int cnt; + t_atom *lst; + }; + + + //! Class representing an "anything" + class FLEXT_SHARE AtomAnything: + public AtomList + { + public: +#if FLEXT_SYS != FLEXT_SYS_JMAX + //! Construct anything + AtomAnything(const t_symbol *h = NULL,int argc = 0,const t_atom *argv = NULL); +#endif + //! Construct anything + AtomAnything(const char *h,int argc = 0,const t_atom *argv = NULL); + //! Construct anything + AtomAnything(const AtomAnything &a); + + //! Clear anything + AtomAnything &Clear() { return operator()(); } + + //! Get header symbol of anything + const t_symbol *Header() const { return hdr; } + + //! Set header symbol of anything + void Header(const t_symbol *h) { hdr = h; } + + //! Set anything + AtomAnything &operator()(const t_symbol *h = NULL,int argc = 0,const t_atom *argv = NULL) + { + hdr = h; AtomList::operator()(argc,argv); + return *this; + } + + //! Set list by another AtomAnything + AtomAnything &operator =(const AtomAnything &a) { return operator()(a.Header(),a.Count(),a.Atoms()); } + + protected: + const t_symbol *hdr; + }; + +//! @} FLEXT_S_ATOM + + +// --- clock stuff ------------------------------------------------ + + + /*! \defgroup FLEXT_S_CLOCK Flext clock functions + + At the moment there are none + + @{ + */ + +//! @} + + +// --- thread stuff ----------------------------------------------- + +#ifdef FLEXT_THREADS + /*! \defgroup FLEXT_S_THREAD Flext thread handling + @{ + */ + + //! thread type +#if FLEXT_THREADS == FLEXT_THR_MP + typedef MPTaskID thrid_t; +#elif FLEXT_THREADS == FLEXT_THR_POSIX + typedef pthread_t thrid_t; +#else +#error +#endif + + /*! \brief Get current thread id + */ + static thrid_t GetThreadId() { +#if FLEXT_THREADS == FLEXT_THR_POSIX + return pthread_self(); +#elif FLEXT_THREADS == FLEXT_THR_MP + return MPCurrentTaskID(); +#else +#error +#endif + } + + /*! \brief Get system thread id + */ + static thrid_t GetSysThreadId() { return thrid; } + + //! Check if current thread is the realtime system's thread + static bool IsThread(thrid_t t,thrid_t ref = GetThreadId()) { +#if FLEXT_THREADS == FLEXT_THR_POSIX + return pthread_equal(ref,t) != 0; +#else + return ref == t; +#endif + } + + //! Check if current thread is the realtime system's thread + static bool IsSystemThread() { return IsThread(GetSysThreadId()); } + + + /*! \brief Thread parameters + \internal + */ + class thr_params + { + public: + thr_params(int n = 1); + ~thr_params(); + + void set_any(const t_symbol *s,int argc,const t_atom *argv); + void set_list(int argc,const t_atom *argv); + + flext_base *cl; + union _data { + bool _bool; + float _float; + int _int; + t_symptr _t_symptr; + struct { AtomAnything *args; } _any; + struct { AtomList *args; } _list; + struct { void *data; } _ext; + } *var; + }; + + /*! \brief This represents an entry to the list of active method threads + \internal + */ + class thr_entry + { + public: + thr_entry(void (*m)(thr_params *),thr_params *p,thrid_t id = GetThreadId()); + + //! \brief Check if this class represents the current thread + bool Is(thrid_t id = GetThreadId()) const { return IsThread(thrid,id); } + + flext_base *This() const { return th; } + thrid_t Id() const { return thrid; } + + flext_base *th; + void (*meth)(thr_params *); + thr_params *params; + thrid_t thrid; + bool active,shouldexit; +#if FLEXT_THREADS == FLEXT_THR_MP + int weight; +#endif + thr_entry *nxt; + }; + +protected: + + static thrid_t thrhelpid; + static bool StartHelper(); + static bool StopHelper(); + static void ThrHelper(void *); + + //! system's thread id + static thrid_t thrid; // the system thread + +public: + + /*! \brief Yield to other threads + \remark A call to this is only needed for systems with cooperative multitasking like MacOS<=9 + */ + static void ThrYield() { +#if FLEXT_THREADS == FLEXT_THR_POSIX + sched_yield(); +#elif FLEXT_THREADS == FLEXT_THR_MP + MPYield(); +#else +#error +#endif + } + + /*! \brief Query whether task is preemptive + */ + static bool IsThreadPreemptive(thrid_t t = GetThreadId()) { +#if FLEXT_THREADS == FLEXT_THR_POSIX || FLEXT_THREADS == FLEXT_THR_WIN32 + return true; +#elif FLEXT_THREADS == FLEXT_THR_MP + return MPTaskIsPreemptive(t); +#else +#error +#endif + } + + + /*! \brief Increase/Decrease priority of a thread + */ + static bool RelPriority(int dp,thrid_t ref = GetSysThreadId(),thrid_t thr = GetThreadId()); + + /*! \brief Get priority of a thread + */ + static int GetPriority(thrid_t thr = GetThreadId()); + + /*! \brief Set priority of a thread + */ + static bool SetPriority(int p,thrid_t thr = GetThreadId()); + + /*! \brief Thread mutex + \sa pthreads documentation + */ + class FLEXT_SHARE ThrMutex +#if FLEXT_THREADS == FLEXT_THR_POSIX + { + public: + //! Construct thread mutex + ThrMutex() /*: cnt(0)*/ { pthread_mutex_init(&mutex,NULL); } + //! Destroy thread mutex + ~ThrMutex() { pthread_mutex_destroy(&mutex); } + + //! Lock thread mutex + bool Lock() { /*cnt = 1;*/ return pthread_mutex_lock(&mutex) == 0; } + //! Lock thread mutex + bool WaitForLock(float tm) { /*cnt = 1;*/ return pthread_mutex_lock(&mutex) == 0; } + //! Try to lock, but don't wait + bool TryLock() { return pthread_mutex_trylock(&mutex) == 0; } + //! Unlock thread mutex + bool Unlock() { /*cnt = 0;*/ return pthread_mutex_unlock(&mutex) == 0; } +/* + //! Lock thread mutex (increase lock count by one) + void Push() { if(!cnt++) Lock(); } + //! Unlock thread mutex if lock count reaches zero + void Pop() { if(!--cnt) Unlock(); } +*/ + protected: + pthread_mutex_t mutex; +// int cnt; + }; +#elif FLEXT_THREADS == FLEXT_THR_MP + { + public: + //! Construct thread mutex + ThrMutex() /*: cnt(0)*/ { MPCreateCriticalRegion(&crit); } + //! Destroy thread mutex + ~ThrMutex() { MPDeleteCriticalRegion(crit); } + + //! Lock thread mutex + bool Lock() { /*cnt = 1;*/ return MPEnterCriticalRegion(crit,kDurationForever) == noErr; } + //! Wait to lock thread mutex + bool WaitForLock(float tm) { /*cnt = 1;*/ return MPEnterCriticalRegion(crit,tm*kDurationMicrosecond*1.e6) == noErr; } + //! Try to lock, but don't wait + bool TryLock() { return MPEnterCriticalRegion(crit,kDurationImmediate) == noErr; } + //! Unlock thread mutex + bool Unlock() { /*cnt = 0;*/ return MPExitCriticalRegion(crit) == noErr; } + + protected: + MPCriticalRegionID crit; + }; +#else +#error "Not implemented" +#endif + + /*! \brief Thread conditional + \sa pthreads documentation + */ + class FLEXT_SHARE ThrCond +#if FLEXT_THREADS == FLEXT_THR_POSIX + :public ThrMutex + { + public: + //! Construct thread conditional + ThrCond() { pthread_cond_init(&cond,NULL); } + //! Destroy thread conditional + ~ThrCond() { pthread_cond_destroy(&cond); } + + //! Wait for condition + bool Wait() { + Lock(); + bool ret = pthread_cond_wait(&cond,&mutex) == 0; + Unlock(); + return ret; + } + + /*! \brief Wait for condition (for a certain time) + \param ftime Wait time in seconds + \ret 0 = signalled, 1 = timed out + \remark Depending on the implementation ftime may not be fractional. + \remark So if ftime = 0 this may suck away your cpu if used in a signalled loop. + */ + bool TimedWait(float ftime) + { + timespec tm; +#if 0 // find out when the following is defined + clock_gettime(CLOCK_REALTIME,tm); + tm.tv_nsec += (long)((ftime-(long)ftime)*1.e9); + long nns = tm.tv_nsec%1000000000; + tm.tv_sec += (long)ftime+(tm.tv_nsec-nns)/1000000000; + tm.tv_nsec = nns; +#else + tm.tv_sec = time(NULL)+(long)ftime; + tm.tv_nsec = 0; +#endif + Lock(); + bool ret = pthread_cond_timedwait(&cond,&mutex,&tm) == 0; + Unlock(); + return ret; + } + + //! Signal condition + bool Signal() + { + Lock(); + bool ret = pthread_cond_signal(&cond) == 0; + Unlock(); + return ret; + } + //! Broadcast condition +// int Broadcast() { return pthread_cond_broadcast(&cond); } + protected: + pthread_cond_t cond; + }; +#elif FLEXT_THREADS == FLEXT_THR_MP + { + public: + //! Construct thread conditional + ThrCond() { MPCreateEvent(&ev); } + //! Destroy thread conditional + ~ThrCond() { MPDeleteEvent(ev); } + + //! Wait for condition + bool Wait() { return MPWaitForEvent(ev,NULL,kDurationForever) == noErr; } + + /*! \brief Wait for condition (for a certain time) + \param time Wait time in seconds + */ + bool TimedWait(float tm) { return MPWaitForEvent(ev,NULL,tm*kDurationMicrosecond*1.e6) == noErr; } + + //! Signal condition + bool Signal() { return MPSetEvent(ev,1) == noErr; } // one bit needs to be set at least + //! Broadcast condition +// int Broadcast() { return pthread_cond_broadcast(&cond); } + protected: + MPEventID ev; + }; +#else +#error "Not implemented" +#endif + + /*! \brief Add current thread to list of active threads + \return true on success + \internal + */ + static bool PushThread(); + + /*! \brief Remove current thread from list of active threads + \internal + */ + static void PopThread(); + + /*! \brief Launch a thread + \remark thr_params *p may be NULL if not needed + */ + static bool LaunchThread(void (*meth)(thr_params *p),thr_params *p); + +//! @} FLEXT_S_THREAD + +#endif // FLEXT_THREADS + +//! @} + +protected: +#ifdef __MRC__ + friend class flext_obj; +#endif + static void Setup(); + + static bool chktilde(const char *objname); +}; + +#endif diff --git a/externals/grill/flext/tutorial/pd/ex-stk2.pd b/externals/grill/flext/tutorial/pd/ex-stk2.pd index 2a4e8ed3..fff665b9 100644 --- a/externals/grill/flext/tutorial/pd/ex-stk2.pd +++ b/externals/grill/flext/tutorial/pd/ex-stk2.pd @@ -1,11 +1,11 @@ -#N canvas 245 28 590 384 12; +#N canvas 245 28 592 386 12; #X obj 68 318 dac~; #X obj 15 8 cnv 15 550 40 empty empty stk2 10 22 0 24 -260818 -1 0 ; #X text 175 28 http://www.parasitaere-kapazitaeten.net; #X text 193 229 adjust the volume; #X obj 194 212 hsl 128 15 0.01 1 1 0 empty empty empty -2 -6 0 8 -261681 --1 -1 0 1; +-1 -1 9000 1; #X obj 68 263 *~ 0.3; #X text 175 8 flext tutorial \, (C)2002-2003 Thomas Grill; #X obj 68 215 stk2~; @@ -13,13 +13,14 @@ #X msg 183 139 shL \$1; #X msg 241 139 shR \$1; #X obj 267 77 hsl 128 15 0.5 2 1 0 empty empty empty -2 -6 0 8 -261681 --1 -1 0 1; +-1 -1 5700 1; #X obj 267 95 hsl 128 15 0.5 2 1 0 empty empty empty -2 -6 0 8 -261681 --1 -1 0 1; +-1 -1 9300 1; #X text 172 73 pitch left; #X text 172 93 pitch right; #X obj 68 78 osc~ 442; #X connect 4 0 5 1; +#X connect 4 0 8 1; #X connect 5 0 0 0; #X connect 7 0 5 0; #X connect 7 1 8 0; diff --git a/externals/grill/flext/tutorial/stk1/stk1.dsp b/externals/grill/flext/tutorial/stk1/stk1.dsp index 2be3c776..ae960092 100644 --- a/externals/grill/flext/tutorial/stk1/stk1.dsp +++ b/externals/grill/flext/tutorial/stk1/stk1.dsp @@ -43,7 +43,7 @@ RSC=rc.exe # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" # ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /YX /FD /c -# ADD CPP /nologo /MT /W3 /GX /O2 /I "..\..\source" /I "f:\prog\packs\sndobj\include" /I "f:\prog\packs\stk\include" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "PD" /D "FLEXT_THREADS" /YX /FD /c +# ADD CPP /nologo /MT /W3 /GX /O2 /I "..\..\source" /I "f:\prog\audio\stk\include" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "PD" /D "FLEXT_THREADS" /YX /FD /c # ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 # ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 # ADD BASE RSC /l 0xc07 /d "NDEBUG" @@ -53,7 +53,7 @@ BSC32=bscmake.exe # ADD BSC32 /nologo LINK32=link.exe # ADD BASE LINK32 kernel32.lib /nologo /dll /machine:I386 -# ADD LINK32 kernel32.lib user32.lib pd.lib pthreadVC.lib flext_t-pdwin.lib stk.lib /nologo /dll /machine:I386 /out:"../pd-msvc/stk1~.dll" /libpath:"..\..\pd-msvc" /libpath:"f:\prog\packs\stk\lib" +# ADD LINK32 kernel32.lib user32.lib pd.lib pthreadVC.lib flext_t-pdwin.lib stk.lib /nologo /dll /machine:I386 /out:"../pd-msvc/stk1~.dll" /libpath:"..\..\pd-msvc" /libpath:"f:\prog\audio\stk\lib" !ELSEIF "$(CFG)" == "stk1 - Win32 Debug" @@ -69,7 +69,7 @@ LINK32=link.exe # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" # ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /YX /FD /GZ /c -# ADD CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /I "..\..\source" /I "f:\prog\packs\sndobj\include" /I "f:\prog\packs\stk\include" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "PD" /D "FLEXT_THREADS" /Fr /YX /FD /GZ /c +# ADD CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /I "..\..\source" /I "f:\prog\audio\stk\include" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "PD" /D "FLEXT_THREADS" /Fr /YX /FD /GZ /c # ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 # ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 # ADD BASE RSC /l 0xc07 /d "_DEBUG" @@ -79,7 +79,7 @@ BSC32=bscmake.exe # ADD BSC32 /nologo LINK32=link.exe # ADD BASE LINK32 kernel32.lib user32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept -# ADD LINK32 kernel32.lib user32.lib pd.lib pthreadVC.lib flext_td-pdwin.lib stk_d.lib /nologo /dll /debug /machine:I386 /out:"msvc-debug/stk1~.dll" /pdbtype:sept /libpath:"..\..\pd-msvc" /libpath:"f:\prog\packs\stk\lib" +# ADD LINK32 kernel32.lib user32.lib pd.lib pthreadVC.lib flext_td-pdwin.lib stk_d.lib /nologo /dll /debug /machine:I386 /out:"msvc-debug/stk1~.dll" /pdbtype:sept /libpath:"..\..\pd-msvc" /libpath:"f:\prog\audio\stk\lib" !ENDIF diff --git a/externals/grill/flext/tutorial/stk2/main.cpp b/externals/grill/flext/tutorial/stk2/main.cpp index 5d6cb72c..bb440c91 100644 --- a/externals/grill/flext/tutorial/stk2/main.cpp +++ b/externals/grill/flext/tutorial/stk2/main.cpp @@ -45,6 +45,7 @@ public: virtual void ProcessObjs(int n); // do DSP processing PitShift *inst[2]; + MY_FLOAT *vec; private: static void Setup(t_class *c); @@ -76,10 +77,13 @@ bool stk2::NewObjs() { bool ok = true; - // set up objects try { + // set up objects for(int i = 0; i < 2; ++i) inst[i] = new PitShift; + + // reserve one signal vector too + vec = new MY_FLOAT[Blocksize()]; } catch (StkError &) { post("%s - Noise() setup failed!",thisName()); @@ -94,16 +98,18 @@ void stk2::FreeObjs() { for(int i = 0; i < 2; ++i) if(inst[i]) delete inst[i]; + if(vec) delete[] vec; } // this is called on every DSP block void stk2::ProcessObjs(int n) { - while(n--) { - MY_FLOAT f = Inlet(0).tick(); - for(int i = 0; i < 2; ++i) - Outlet(i).tick(inst[i]->tick(f)); - } + for(int i = 0; i < 2; ++i) + Outlet(i).tick( + inst[i]->tick( + Inlet(0).tick(vec,n) + ,n) + ,n); } diff --git a/externals/grill/flext/tutorial/stk2/stk2.dsp b/externals/grill/flext/tutorial/stk2/stk2.dsp index 8ace2bf9..26cba580 100644 --- a/externals/grill/flext/tutorial/stk2/stk2.dsp +++ b/externals/grill/flext/tutorial/stk2/stk2.dsp @@ -43,7 +43,7 @@ RSC=rc.exe # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" # ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /YX /FD /c -# ADD CPP /nologo /MT /W3 /GX /O2 /I "..\..\source" /I "f:\prog\packs\sndobj\include" /I "f:\prog\packs\stk\include" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "PD" /D "FLEXT_THREADS" /YX /FD /c +# ADD CPP /nologo /MT /W3 /GX /O2 /I "..\..\source" /I "f:\prog\audio\stk\include" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "PD" /D "FLEXT_THREADS" /YX /FD /c # ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 # ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 # ADD BASE RSC /l 0xc07 /d "NDEBUG" @@ -53,7 +53,7 @@ BSC32=bscmake.exe # ADD BSC32 /nologo LINK32=link.exe # ADD BASE LINK32 kernel32.lib /nologo /dll /machine:I386 -# ADD LINK32 kernel32.lib user32.lib pd.lib pthreadVC.lib flext_t-pdwin.lib stk.lib /nologo /dll /machine:I386 /out:"../pd-msvc/stk2~.dll" /libpath:"..\..\pd-msvc" /libpath:"f:\prog\packs\stk\lib" +# ADD LINK32 kernel32.lib user32.lib pd.lib pthreadVC.lib flext_t-pdwin.lib stk.lib /nologo /dll /machine:I386 /out:"../pd-msvc/stk2~.dll" /libpath:"..\..\pd-msvc" /libpath:"f:\prog\audio\stk\lib" !ELSEIF "$(CFG)" == "stk2 - Win32 Debug" @@ -69,7 +69,7 @@ LINK32=link.exe # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" # ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /YX /FD /GZ /c -# ADD CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /I "..\..\source" /I "f:\prog\packs\sndobj\include" /I "f:\prog\packs\stk\include" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "PD" /D "FLEXT_THREADS" /Fr /YX /FD /GZ /c +# ADD CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /I "..\..\source" /I "f:\prog\audio\stk\include" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "PD" /D "FLEXT_THREADS" /Fr /YX /FD /GZ /c # ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 # ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 # ADD BASE RSC /l 0xc07 /d "_DEBUG" @@ -79,7 +79,7 @@ BSC32=bscmake.exe # ADD BSC32 /nologo LINK32=link.exe # ADD BASE LINK32 kernel32.lib user32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept -# ADD LINK32 kernel32.lib user32.lib pd.lib pthreadVC.lib flext_td-pdwin.lib stk_d.lib /nologo /dll /debug /machine:I386 /out:"msvc-debug/stk2~.dll" /pdbtype:sept /libpath:"..\..\pd-msvc" /libpath:"f:\prog\packs\stk\lib" +# ADD LINK32 kernel32.lib user32.lib pd.lib pthreadVC.lib flext_td-pdwin.lib stk_d.lib /nologo /dll /debug /machine:I386 /out:"msvc-debug/stk2~.dll" /pdbtype:sept /libpath:"..\..\pd-msvc" /libpath:"f:\prog\audio\stk\lib" !ENDIF diff --git a/externals/grill/guitest/guitest.dsp b/externals/grill/guitest/guitest.dsp index e7dcf20e..e1f326ce 100644 --- a/externals/grill/guitest/guitest.dsp +++ b/externals/grill/guitest/guitest.dsp @@ -43,7 +43,7 @@ RSC=rc.exe # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" # ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "GUITEST_EXPORTS" /YX /FD /c -# ADD CPP /nologo /W3 /GR /O2 /I "c:\programme\audio\pd\src" /I "f:\prog\max\flext\source" /I "F:\prog\packs\wxwindows-2.3.2\include" /I "F:\prog\packs\wxwindows-2.3.2\lib\mswdll" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "NT" /D "PD" /YX /FD /c +# ADD CPP /nologo /W3 /GR /O2 /I "F:\prog\pd\pd-cvs\src" /I "f:\prog\max\flext\source" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "NT" /D "PD" /YX /FD /c # SUBTRACT CPP /Fr # ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 # ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 @@ -54,7 +54,7 @@ BSC32=bscmake.exe # ADD BSC32 /nologo LINK32=link.exe # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.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-pdwin.lib /nologo /dll /machine:I386 /libpath:"c:\programme\audio\pd\bin" /libpath:"f:\prog\max\flext\pd-msvc" /libpath:"F:\prog\packs\wxwindows-2.2.9\lib" +# ADD LINK32 kernel32.lib user32.lib pd.lib flext-pdwin.lib /nologo /dll /machine:I386 /libpath:"f:\prog\pd\pd-cvs\bin" /libpath:"f:\prog\max\flext\pd-msvc" !ELSEIF "$(CFG)" == "guitest - Win32 Debug" @@ -70,7 +70,7 @@ LINK32=link.exe # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" # ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "GUITEST_EXPORTS" /YX /FD /GZ /c -# ADD CPP /nologo /W3 /Gm /GR /ZI /Od /I "c:\programme\audio\pd\src" /I "f:\prog\max\flext\source" /I "F:\prog\packs\wxwindows-2.3.2\include" /I "F:\prog\packs\wxwindows-2.3.2\lib\mswdlld" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "NT" /D "PD" /FR /YX /FD /GZ /c +# ADD CPP /nologo /W3 /Gm /GR /ZI /Od /I "F:\prog\pd\pd-cvs\src" /I "f:\prog\max\flext\source" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "NT" /D "PD" /FR /YX /FD /GZ /c # ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 # ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 # ADD BASE RSC /l 0xc07 /d "_DEBUG" @@ -80,7 +80,7 @@ BSC32=bscmake.exe # ADD BSC32 /nologo LINK32=link.exe # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept -# ADD LINK32 kernel32.lib user32.lib gdi32.lib pd.lib flext_d-pdwin.lib /nologo /dll /debug /machine:I386 /pdbtype:sept /libpath:"c:\programme\audio\pd\bin" /libpath:"f:\prog\max\flext\pd-msvc" /libpath:"F:\prog\packs\wxwindows-2.3.2\lib" +# ADD LINK32 kernel32.lib user32.lib gdi32.lib pd.lib flext_d-pdwin.lib /nologo /dll /debug /machine:I386 /pdbtype:sept /libpath:"f:\prog\pd\pd-cvs\bin" /libpath:"f:\prog\max\flext\pd-msvc" !ENDIF diff --git a/externals/grill/pool/data.cpp b/externals/grill/pool/data.cpp index 8d5d41c4..8ea6cc57 100644 --- a/externals/grill/pool/data.cpp +++ b/externals/grill/pool/data.cpp @@ -252,10 +252,9 @@ BL pooldata::LdDirXML(const AtomList &d,const C *flnm,I depth,BL mkdir) ret = pd->LdDirXML(fl,depth,mkdir); return ret; } - else return false; } - else - return false; + + return false; } BL pooldata::SvDirXML(const AtomList &d,const C *flnm,I depth,BL absdir) @@ -277,10 +276,9 @@ BL pooldata::SvDirXML(const AtomList &d,const C *flnm,I depth,BL absdir) return ret; } } - else return false; } - else - return false; + + return false; } diff --git a/externals/grill/pool/readme.txt b/externals/grill/pool/readme.txt index 62e42669..f759ae85 100644 --- a/externals/grill/pool/readme.txt +++ b/externals/grill/pool/readme.txt @@ -1,78 +1,80 @@ -pool - a hierarchical storage object for PD and Max/MSP - -Copyright (c) 2002-2003 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. - -Donations for further development of the package are highly appreciated. - ----------------------------------------------------------------------------- - -You will need the flext C++ layer for PD and Max/MSP externals to compile this. - -Package files: -- readme.txt: this one -- gpl.txt,license.txt: GPL license stuff -- main.cpp, pool.h, pool.cpp, data.cpp - ----------------------------------------------------------------------------- - -Goals/features of the package: - -- pool can store and retrieve key/value pairs, where a key can be any atom and - the value can be any list of atoms -- pool can manage folders. A folder name can be any atom. -- pool objects can be named and then share their data space -- clipboard operations are possible in a pool or among several pools -- file operations can load/save data from disk - ----------------------------------------------------------------------------- - -The package should at least compile (and is tested) with the following compilers: - -pd - Windows: -------------- -o Borland C++ 5.5 (free): edit "config-pd-bcc.txt" & run "build-pd-bcc.bat" - -o Microsoft Visual C++ 6: edit the project file "pool.dsp" & build - -pd - linux: ------------ -o GCC: edit "config-pd-linux.txt" & run "sh build-pd-linux.sh" - -pd - darwin (MacOSX): ---------------------- -o GCC: edit "config-pd-darwin.txt" & run "sh build-pd-darwin.sh" - -Max/MSP - MacOS9: ------------------ -o CodeWarrior: edit "pool.cw" and build - ----------------------------------------------------------------------------- - -Version history: - -0.2.0: -- attributes (pool,private,echodir,absdir) -- added "geti" message for retrieval of a value at an index -- fixed bug in "get" message if key not present -- adapted source to flext 0.4.1 - register methods at class creation -- extensive use of hashing for keys and directories -- database can be saved/loaded as XML data - -0.1.0: -- first public release - ---------------------------------------------------------------------------- - -BUGS: -- pool does not handle symbols with spaces or all digits - - -TODO list: - -general: -- speed up the database -- what is output as value if it is key only? (Max->nothing!) - - +pool - a hierarchical storage object for PD and Max/MSP + +Copyright (c) 2002-2003 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. + +Donations for further development of the package are highly appreciated. + +---------------------------------------------------------------------------- + +You will need the flext C++ layer for PD and Max/MSP externals to compile this. +see http://www.parasitaere-kapazitaeten.net/ext + + +Package files: +- readme.txt: this one +- gpl.txt,license.txt: GPL license stuff +- main.cpp, pool.h, pool.cpp, data.cpp + +---------------------------------------------------------------------------- + +Goals/features of the package: + +- pool can store and retrieve key/value pairs, where a key can be any atom and + the value can be any list of atoms +- pool can manage folders. A folder name can be any atom. +- pool objects can be named and then share their data space +- clipboard operations are possible in a pool or among several pools +- file operations can load/save data from disk + +---------------------------------------------------------------------------- + +The package should at least compile (and is tested) with the following compilers: + +pd - Windows: +------------- +o Borland C++ 5.5 (free): edit "config-pd-bcc.txt" & run "build-pd-bcc.bat" + +o Microsoft Visual C++ 6: edit the project file "pool.dsp" & build + +pd - linux: +----------- +o GCC: edit "config-pd-linux.txt" & run "sh build-pd-linux.sh" + +pd - darwin (MacOSX): +--------------------- +o GCC: edit "config-pd-darwin.txt" & run "sh build-pd-darwin.sh" + +Max/MSP - MacOS9: +----------------- +o CodeWarrior: edit "pool.cw" and build + +---------------------------------------------------------------------------- + +Version history: + +0.2.0: +- attributes (pool,private,echodir,absdir) +- added "geti" message for retrieval of a value at an index +- fixed bug in "get" message if key not present +- adapted source to flext 0.4.1 - register methods at class creation +- extensive use of hashing for keys and directories +- database can be saved/loaded as XML data + +0.1.0: +- first public release + +--------------------------------------------------------------------------- + +BUGS: +- pool does not handle symbols with spaces or all digits + + +TODO list: + +general: +- speed up the database +- what is output as value if it is key only? (Max->nothing!) + + diff --git a/externals/grill/py/readme.txt b/externals/grill/py/readme.txt index 3c0cdb43..2b791f18 100644 --- a/externals/grill/py/readme.txt +++ b/externals/grill/py/readme.txt @@ -1,121 +1,123 @@ -py/pyext - python script objects for PD (and MaxMSP... once, under MacOSX and Windows) - -Copyright (c) 2002-2003 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. - -Donations for further development of the package are highly appreciated. - ----------------------------------------------------------------------------- - -You will need the flext C++ layer for PD and Max/MSP externals to compile this. - -Package files: -- readme.txt: this one -- gpl.txt,license.txt: GPL license stuff -- main.cpp, main.h, modmeth.cpp, pyargs.cpp, register.cpp: base class -- py.cpp: py object -- pyext.cpp, pyext.h, clmeth.cpp, bound.cpp: pyext object - ----------------------------------------------------------------------------- - -Goals/features of the package: - -Access the flexibility of the python language in PD and MaxMSP - - -PD - Load it as i library with e.g. "pd -lib py -path scripts" -Max/MSP - Wait for Windows or MacOSX version. MacOS9 doesn't want it. - - -Check out the sample patches and scripts - - -Description: - -With the py object you can load python modules and execute the functions therein. -With the pyext you can use python classes to represent full-featured pd/Max message objects. -Multithreading (detached methods) is supported for both objects. -You can send messages to named objects or receive (with pyext) with Python methods. - - -Known bugs: -There are problems with importing the "time" module, experienced with Python 2.2.2 under OSX. -Therefore, some help patches may not be functional. - ----------------------------------------------------------------------------- - -The py/pyext package should run with Python version >= 2.1. -It has been thoroughly tested with version 2.2 - - -The package should at least compile (and is tested) with the following compilers: - -PD @ Windows: -------------- -o Borland C++ 5.5 (free): edit "config-pd-bcc.txt" & run "build-pd-bcc.bat" - -o Microsoft Visual C++ 6: usr "py.dsp" or edit "config-pd-msvc.txt" & run "build-pd-msvc.bat" - -PD @ linux: ------------ -Python doesn't provide a shared lib by default - static linking produces huge externals -Ok, debian is an exception... the precompiled binary is for debian, therefore. - -o GCC: edit "config-pd-linux.txt" & run "sh build-pd-linux.sh" - -PD @ MacOSX: ---------------------- - -o GCC: edit "config-pd-darwin.txt" & run "sh build-pd-darwin.sh" - ----------------------------------------------------------------------------- - -Version history: - -0.1.2: -- CHANGE: updates for flext 0.4.1 - method registering within class scope - -0.1.1: -- CHANGE: updates for flext 0.4.0 -- FIX: crash when module couldn't be loaded -- FIX: GetBound method (modmeth.cpp, line 138) doesn't exist in flext any more -- FIX: deadlock occured when connecting to py/pyext boxes in non-detached mode -- ADD: current path and path of the canvas is added to the python path -- FIX: path is not added to python path if already included - -0.1.0: -- completely reworked all code -- added class functionality for full-featured objects and renamed the merge to pyext -- enabled threads and made everything thread-safe ... phew! -- using flext 0.3.2 -- pyext now gets full python path -- python's argv[0] is now "py" or "pyext" -- etc.etc. - -0.0.2: -- fixed bug when calling script with no function defined (thanks to Ben Saylor) -- cleaner gcc makefile - -0.0.1: -- using flext 0.2.1 - ---------------------------------------------------------------------------- - -TODO list: - -general: -- Documentation and better example patches - -features: -- enable multiple interpreters? -- make a pygui object where Tkinter draws to the PD canvas... -- stop individual threads - -tests: -- check for python threading support - -bugs: -- the python interpreter can't be unloaded due to some bug at re-initialization -- named (keyword) arguments are not supported - +py/pyext - python script objects for PD (and MaxMSP... once, under MacOSX and Windows) + +Copyright (c) 2002-2003 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. + +Donations for further development of the package are highly appreciated. + +---------------------------------------------------------------------------- + +You will need the flext C++ layer for PD and Max/MSP externals to compile this. +see http://www.parasitaere-kapazitaeten.net/ext + + +Package files: +- readme.txt: this one +- gpl.txt,license.txt: GPL license stuff +- main.cpp, main.h, modmeth.cpp, pyargs.cpp, register.cpp: base class +- py.cpp: py object +- pyext.cpp, pyext.h, clmeth.cpp, bound.cpp: pyext object + +---------------------------------------------------------------------------- + +Goals/features of the package: + +Access the flexibility of the python language in PD and MaxMSP + + +PD - Load it as i library with e.g. "pd -lib py -path scripts" +Max/MSP - Wait for Windows or MacOSX version. MacOS9 doesn't want it. + + +Check out the sample patches and scripts + + +Description: + +With the py object you can load python modules and execute the functions therein. +With the pyext you can use python classes to represent full-featured pd/Max message objects. +Multithreading (detached methods) is supported for both objects. +You can send messages to named objects or receive (with pyext) with Python methods. + + +Known bugs: +There are problems with importing the "time" module, experienced with Python 2.2.2 under OSX. +Therefore, some help patches may not be functional. + +---------------------------------------------------------------------------- + +The py/pyext package should run with Python version >= 2.1. +It has been thoroughly tested with version 2.2 + + +The package should at least compile (and is tested) with the following compilers: + +PD @ Windows: +------------- +o Borland C++ 5.5 (free): edit "config-pd-bcc.txt" & run "build-pd-bcc.bat" + +o Microsoft Visual C++ 6: usr "py.dsp" or edit "config-pd-msvc.txt" & run "build-pd-msvc.bat" + +PD @ linux: +----------- +Python doesn't provide a shared lib by default - static linking produces huge externals +Ok, debian is an exception... the precompiled binary is for debian, therefore. + +o GCC: edit "config-pd-linux.txt" & run "sh build-pd-linux.sh" + +PD @ MacOSX: +--------------------- + +o GCC: edit "config-pd-darwin.txt" & run "sh build-pd-darwin.sh" + +---------------------------------------------------------------------------- + +Version history: + +0.1.2: +- CHANGE: updates for flext 0.4.1 - method registering within class scope + +0.1.1: +- CHANGE: updates for flext 0.4.0 +- FIX: crash when module couldn't be loaded +- FIX: GetBound method (modmeth.cpp, line 138) doesn't exist in flext any more +- FIX: deadlock occured when connecting to py/pyext boxes in non-detached mode +- ADD: current path and path of the canvas is added to the python path +- FIX: path is not added to python path if already included + +0.1.0: +- completely reworked all code +- added class functionality for full-featured objects and renamed the merge to pyext +- enabled threads and made everything thread-safe ... phew! +- using flext 0.3.2 +- pyext now gets full python path +- python's argv[0] is now "py" or "pyext" +- etc.etc. + +0.0.2: +- fixed bug when calling script with no function defined (thanks to Ben Saylor) +- cleaner gcc makefile + +0.0.1: +- using flext 0.2.1 + +--------------------------------------------------------------------------- + +TODO list: + +general: +- Documentation and better example patches + +features: +- enable multiple interpreters? +- make a pygui object where Tkinter draws to the PD canvas... +- stop individual threads + +tests: +- check for python threading support + +bugs: +- the python interpreter can't be unloaded due to some bug at re-initialization +- named (keyword) arguments are not supported + diff --git a/externals/grill/xsample/readme.txt b/externals/grill/xsample/readme.txt index 07aa5a6a..0fc6fabe 100644 --- a/externals/grill/xsample/readme.txt +++ b/externals/grill/xsample/readme.txt @@ -1,152 +1,153 @@ -xsample - extended sample objects for Max/MSP and pd (pure data) - -Copyright (c) 2001-2003 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. - -Donations for further development of the package are highly appreciated. - ----------------------------------------------------------------------------- - -IMPORTANT INFORMATION for all MaxMSP users: - -It is advisable to put the xsample shared library file into the "max-startup" folder. Hence it will be -loaded at Max startup. - -If you want to load the xsample library on demand, create a [xsample] object in Max/MSP. - ----------------------------------------------------------------------------- - -You will need the flext C++ layer for PD and Max/MSP externals to compile this. - - -Package files: -- readme.txt: this one -- gpl.txt,license.txt: GPL license stuff -- main.h,main.cpp,inter.cpp,inter.ci: base class definition for all the other objects -- record.cpp: xrecord~ -- play.cpp: xplay~ -- groove.cpp: xgroove~ - ----------------------------------------------------------------------------- - -The package should at least compile (and is tested) with the following compilers: - -pd - Windows: -------------- -o Borland C++ 5.5 (free): edit & run "make -f makefile.bcc" - -o Microsoft Visual C++ 6: edit "xsample.dsp" project file -> due to a compiler bug the optimization using templates is not functional - -pd - linux: ------------ -o GCC: edit "config-pd-linux.txt" and run "sh ./build-pd-linux.sh" -> various versions of GCC die during compile with template optimization turned on - -pd - OSX: ------------ -o GCC: edit "config-pd-darwin.txt" and run "sh ./build-pd-darwin.sh" -> various versions of GCC die during compile with template optimization turned on - -Max/MSP - MacOS9: ----------------- -o Metrowerks CodeWarrior: edit "xsample.cw" project file functions - -o Apple MPW-PR: edit & use the "flext.mpw" makefile - -Max/MSP - MacOSX: ----------------- -o Metrowerks CodeWarrior: edit "xsample.cw" project file functions - - ----------------------------------------------------------------------------- - -Goals/features of the package: - -- portable and effective sample recording/playing objects for pd and Max/MSP -- MSP-like groove~ object for PD -- message- or signal-triggered recording object with mix-in capability -- avoid the various bugs of the original MSP2 objects -- multi-channel capability -- live update of respective buffer/array content -- switchable 4-point or linear interpolation for xplay~/xgroove~ object -- cross-fading loop zone (inside or outside to loop) for xgroove~ - ----------------------------------------------------------------------------- - -Version history: - -0.3.0: -- added resources to MaxMSP build -- xgroove~, xrecord~: introduced a loop/end bang outlet -- added MaxMSP buffer resize recognition -- xgroove~: introduced a crossfading loop zone -- adapted source for flext 0.4.1 - most methods within class scope -- introduced attributes -- restructured make procedures -- corrected names of PD makefile, set help names -- fixed scale mode bug with xgroove~ -- added validity check for buffers - -0.2.4: -- according to flext 0.2.3 changed sample type to t_sample (S) -- xrecord~: fixed mix mode bug -- fixed argument buffer problem - -0.2.3: -- using flext 0.2.2 - xsample is now a library under MaxMSP -- cleaner gcc makefile -- xgroove~, xrecord~: added "all" message to select entire buffer length -- xgroove~, xplay~: revisited dsp methods, restructured the code, fixed small interpolation bugs -- xgroove~, xplay~: added linear interpolation (message "interp 2") -- enabled 0 output channels -> xgroove~: position output only -- xgroove~: added bidirectional looping (message "loop 2") - -0.2.2: -- using flext 0.2.0 -- xrecord~ for PD: new flext brings better graphics update behavior -- xrecord~: recording position doesn't jump to start when recording length is reached -- fixed bug with refresh message (min/max reset) -- xgroove~: position (by pos message) isn't sample rounded anymore -- reset/refresh messages readjust dsp routines to current buffer format (e.g. channel count) -- corrected Max/MSP assist method for multi-channel -- fixed xplay~ help method -- changed syntax to x*~ [channels=1] [buffer] for future enhancements (MaxMSP only, warning for old syntax) -- fixed small bug concerning startup position in xgroove~ and xrecord~ -- fixed deadly bug in xplay~ dsp code (only active with template optimization) - -0.2.1: -- no leftmost float inlet for position setting - use pos method -- changed dsp handling for flext 0.1.1 conformance -- workarounds for buggy/incomplete compilers -- prevent buffer warning message at patcher load (wait for loadbang) -- fixed bug: current pos is reset when changing min or max points - -0.2.0: -- first version for flext - ---------------------------------------------------------------------------- - - -TODO list: - -general: - -- do a smooth (line~) mixin in xrecord~ help patch - -features: -- multi-buffer handling (aka multi-channel for pd) -- vasp handling -- performance comparison to respective PD/Max objects -- anti-alias filter? (possible?) - -- delay min/max changes when cur pos in cross-fade zone - -tests: -- reconsider startup sequence of set buffer,set units,set sclmode,set pos/min/max - -bugs: -- PD: problems with timed buffer redrawing (takes a lot of cpu time) - flext bug? -- Apple MPW doesn't correctly compile template optimization -- Max help files aren't correctly opened due to xsample objects residing in a library +xsample - extended sample objects for Max/MSP and pd (pure data) + +Copyright (c) 2001-2003 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. + +Donations for further development of the package are highly appreciated. + +---------------------------------------------------------------------------- + +IMPORTANT INFORMATION for all MaxMSP users: + +It is advisable to put the xsample shared library file into the "max-startup" folder. Hence it will be +loaded at Max startup. + +If you want to load the xsample library on demand, create a [xsample] object in Max/MSP. + +---------------------------------------------------------------------------- + +You will need the flext C++ layer for PD and Max/MSP externals to compile this. +see http://www.parasitaere-kapazitaeten.net/ext + + +Package files: +- readme.txt: this one +- gpl.txt,license.txt: GPL license stuff +- main.h,main.cpp,inter.cpp,inter.ci: base class definition for all the other objects +- record.cpp: xrecord~ +- play.cpp: xplay~ +- groove.cpp: xgroove~ + +---------------------------------------------------------------------------- + +The package should at least compile (and is tested) with the following compilers: + +pd - Windows: +------------- +o Borland C++ 5.5 (free): edit & run "make -f makefile.bcc" + +o Microsoft Visual C++ 6: edit "xsample.dsp" project file +> due to a compiler bug the optimization using templates is not functional + +pd - linux: +----------- +o GCC: edit "config-pd-linux.txt" and run "sh ./build-pd-linux.sh" +> various versions of GCC die during compile with template optimization turned on + +pd - OSX: +----------- +o GCC: edit "config-pd-darwin.txt" and run "sh ./build-pd-darwin.sh" +> various versions of GCC die during compile with template optimization turned on + +Max/MSP - MacOS9: +---------------- +o Metrowerks CodeWarrior: edit "xsample.cw" project file functions + +o Apple MPW-PR: edit & use the "flext.mpw" makefile + +Max/MSP - MacOSX: +---------------- +o Metrowerks CodeWarrior: edit "xsample.cw" project file functions + + +---------------------------------------------------------------------------- + +Goals/features of the package: + +- portable and effective sample recording/playing objects for pd and Max/MSP +- MSP-like groove~ object for PD +- message- or signal-triggered recording object with mix-in capability +- avoid the various bugs of the original MSP2 objects +- multi-channel capability +- live update of respective buffer/array content +- switchable 4-point or linear interpolation for xplay~/xgroove~ object +- cross-fading loop zone (inside or outside to loop) for xgroove~ + +---------------------------------------------------------------------------- + +Version history: + +0.3.0: +- added resources to MaxMSP build +- xgroove~, xrecord~: introduced a loop/end bang outlet +- added MaxMSP buffer resize recognition +- xgroove~: introduced a crossfading loop zone +- adapted source for flext 0.4.1 - most methods within class scope +- introduced attributes +- restructured make procedures +- corrected names of PD makefile, set help names +- fixed scale mode bug with xgroove~ +- added validity check for buffers + +0.2.4: +- according to flext 0.2.3 changed sample type to t_sample (S) +- xrecord~: fixed mix mode bug +- fixed argument buffer problem + +0.2.3: +- using flext 0.2.2 - xsample is now a library under MaxMSP +- cleaner gcc makefile +- xgroove~, xrecord~: added "all" message to select entire buffer length +- xgroove~, xplay~: revisited dsp methods, restructured the code, fixed small interpolation bugs +- xgroove~, xplay~: added linear interpolation (message "interp 2") +- enabled 0 output channels -> xgroove~: position output only +- xgroove~: added bidirectional looping (message "loop 2") + +0.2.2: +- using flext 0.2.0 +- xrecord~ for PD: new flext brings better graphics update behavior +- xrecord~: recording position doesn't jump to start when recording length is reached +- fixed bug with refresh message (min/max reset) +- xgroove~: position (by pos message) isn't sample rounded anymore +- reset/refresh messages readjust dsp routines to current buffer format (e.g. channel count) +- corrected Max/MSP assist method for multi-channel +- fixed xplay~ help method +- changed syntax to x*~ [channels=1] [buffer] for future enhancements (MaxMSP only, warning for old syntax) +- fixed small bug concerning startup position in xgroove~ and xrecord~ +- fixed deadly bug in xplay~ dsp code (only active with template optimization) + +0.2.1: +- no leftmost float inlet for position setting - use pos method +- changed dsp handling for flext 0.1.1 conformance +- workarounds for buggy/incomplete compilers +- prevent buffer warning message at patcher load (wait for loadbang) +- fixed bug: current pos is reset when changing min or max points + +0.2.0: +- first version for flext + +--------------------------------------------------------------------------- + + +TODO list: + +general: + +- do a smooth (line~) mixin in xrecord~ help patch + +features: +- multi-buffer handling (aka multi-channel for pd) +- vasp handling +- performance comparison to respective PD/Max objects +- anti-alias filter? (possible?) + +- delay min/max changes when cur pos in cross-fade zone + +tests: +- reconsider startup sequence of set buffer,set units,set sclmode,set pos/min/max + +bugs: +- PD: problems with timed buffer redrawing (takes a lot of cpu time) - flext bug? +- Apple MPW doesn't correctly compile template optimization +- Max help files aren't correctly opened due to xsample objects residing in a library -- cgit v1.2.1