diff options
author | Thomas Grill <xovo@users.sourceforge.net> | 2005-01-08 04:59:44 +0000 |
---|---|---|
committer | Thomas Grill <xovo@users.sourceforge.net> | 2005-01-08 04:59:44 +0000 |
commit | eba585829684fcf54a0c8614709d2c10c75032b4 (patch) | |
tree | 9f4e2ca184f37852fd5c5d8e30df10b100f25ffd /externals/grill/xsample/source/main.h | |
parent | 0709ac9fabf4184675df1c3d8e205a2790adaadb (diff) |
merge in branch "20041229-unify"
- some small cleanups
os x fixes
minor updates
improved buffer handling
simplify updates
Mac adaptations
- made xcode project
preparing xsample 0.3.0 release
updated for build system
some optimizations
- fixed loop record bug
Completion of attribute functionality, revisited and updated help files
svn path=/trunk/; revision=2477
Diffstat (limited to 'externals/grill/xsample/source/main.h')
-rw-r--r-- | externals/grill/xsample/source/main.h | 306 |
1 files changed, 203 insertions, 103 deletions
diff --git a/externals/grill/xsample/source/main.h b/externals/grill/xsample/source/main.h index 3608a55c..97e4516d 100644 --- a/externals/grill/xsample/source/main.h +++ b/externals/grill/xsample/source/main.h @@ -1,11 +1,9 @@ /* - xsample - extended sample objects for Max/MSP and pd (pure data) -Copyright (c) 2001-2004 Thomas Grill (xovo@gmx.net) +Copyright (c) 2001-2005 Thomas Grill (gr@grrrr.org) For information on usage and redistribution, and for a DISCLAIMER OF ALL WARRANTIES, see the file, "license.txt," in this distribution. - */ #ifndef __XSAMPLE_H @@ -13,18 +11,19 @@ WARRANTIES, see the file, "license.txt," in this distribution. #include "prefix.h" -#if !defined(FLEXT_VERSION) || (FLEXT_VERSION < 406) -#error You need at least flext version 0.4.6 +#if !defined(FLEXT_VERSION) || (FLEXT_VERSION < 500) +#error You need at least flext version 0.5.0 #endif -#define XSAMPLE_VERSION "0.3.1pre3" +#define XSAMPLE_VERSION "0.3.1pre4" // most compilers are somehow broken - in other words - can't handle all C++ features #if defined(_MSC_VER) // MS VC 6.0 can't handle <int,int> templates?! -> no optimization - #if _MSC_VER >= 1300 +// MS VC .NET 2002 just dies with template optimization switched on + #if _MSC_VER >= 1310 #define TMPLOPT #endif #elif defined(__BORLANDC__) @@ -51,17 +50,6 @@ WARRANTIES, see the file, "license.txt," in this distribution. #endif -// lazy me -#define F float -#define D double -#define I int -#define L long -#define C char -#define V void -#define BL bool -#define S t_sample - - #if defined(__MWERKS__) && !defined(__MACH__) #define STD std #else @@ -92,6 +80,32 @@ WARRANTIES, see the file, "license.txt," in this distribution. } #endif +#if FLEXT_CPU == FLEXT_CPU_INTEL && defined(__GNUC__) +template<typename I,typename F> inline I CASTINT(F o) { return lrintf(o); } +#elif FLEXT_CPU == FLEXT_CPU_INTEL && defined(_MSC_VER) +template<typename I,typename F> +inline I CASTINT(F x) { +// by Laurent de Soras (http://ldesoras.free.fr) +// assert (x > static_cast <double> (INT_MIN / 2) + 1.0); +// assert (x < static_cast <double> (INT_MAX / 2) + 1.0); + const float round_towards_m_i = -0.5f; + I i; + __asm + { + fld x + fadd st,st + fabs + fadd round_towards_m_i + fistp i + sar i, 1 + } + if(x < 0) i = -i; + return i; +} +#else +template<typename I,typename F> inline I CASTINT(F o) { return static_cast<I>(o); } +#endif + class xsample: public flext_dsp @@ -101,73 +115,133 @@ class xsample: public: xsample(); ~xsample(); + + enum xs_change { + xsc__ = 0, + xsc_units = 0x0001, + xsc_play = 0x0002, + xsc_pos = 0x0008, + xsc_range = 0x0010, + xsc_transport = 0x0020, + xsc_fade = 0x0040, + + xsc_intp = xsc_play, + xsc_srate = xsc_play|xsc_units, + xsc_chns = xsc_play, + xsc_loop = xsc_play, + xsc_startstop = xsc_play|xsc_transport, + xsc_buffer = xsc_units|xsc_pos|xsc_range|xsc_play, + xsc_reset = xsc_buffer, + xsc_all = 0xffff + }; - enum xs_unit { - xsu__ = -1, // don't change - xsu_sample = 0,xsu_buffer,xsu_ms,xsu_s - }; + enum xs_unit { + xsu_sample = 0,xsu_buffer,xsu_ms,xsu_s + }; enum xs_intp { - xsi__ = -1, // don't change xsi_none = 0,xsi_4p,xsi_lin }; enum xs_sclmd { - xss__ = -1, // don't change xss_unitsinbuf = 0,xss_unitsinloop,xss_buffer,xss_loop }; protected: - buffer *buf; - - virtual V m_start() = 0; - virtual V m_stop() = 0; - virtual BL m_reset(); - - virtual I m_set(I argc,const t_atom *argv); - virtual V m_print() = 0; - virtual BL m_refresh(); - virtual V m_loadbang(); - - virtual V m_units(xs_unit u = xsu__); - virtual V m_sclmode(xs_sclmd u = xss__); - - virtual V m_all(); - virtual V m_min(F mn); - virtual V m_max(F mx); - - virtual V m_dsp(I n,S *const *insigs,S *const *outsigs); - virtual V s_dsp() = 0; - - xs_unit unitmode; //iunitmode,ounitmode; - xs_sclmd sclmode; //isclmode,osclmode; - - L curmin,curmax; //,curlen; // in samples - I sclmin; // in samples - F sclmul; - F s2u; // sample to unit conversion factor - - inline F scale(F smp) const { return (smp-sclmin)*sclmul; } + virtual bool Finalize(); + + buffer buf; + + void m_reset() + { + ChkBuffer(true); + DoReset(); + Refresh(); + } + + void m_set(int argc,const t_atom *argv); + + void m_refresh() + { + Update(xsc_buffer,true); + } + + void m_units(xs_unit mode) + { + unitmode = mode; + Update(xsc_units,true); + } + + void m_sclmode(xs_sclmd mode) + { + sclmode = mode; + Update(xsc_units,true); + } + + void m_all() + { + ChkBuffer(true); + ResetRange(); + Refresh(); + } + + void m_min(float mn); + void m_max(float mx); + + xs_unit unitmode; + xs_sclmd sclmode; + + long curmin,curmax; //,curlen; // in samples + long sclmin; // in samples + float sclmul; + float s2u; // sample to unit conversion factor + + inline float scale(float smp) const { return (smp-sclmin)*sclmul; } - static V arrscale(I n,const S *in,S *out,S add,S mul) { flext::ScaleSamples(out,in,mul,add,n); } - inline V arrscale(I n,const S *in,S *out) const { arrscale(n,in,out,-sclmin*sclmul,sclmul); } + static void arrscale(int n,const t_sample *in,t_sample *out,t_sample add,t_sample mul) { flext::ScaleSamples(out,in,mul,add,n); } + inline void arrscale(int n,const t_sample *in,t_sample *out) const { arrscale(n,in,out,-sclmin*sclmul,sclmul); } - static V arrmul(I n,const S *in,S *out,S mul) { flext::MulSamples(out,in,mul,n); } - inline V arrmul(I n,const S *in,S *out) const { arrmul(n,in,out,(S)(1./s2u)); } - - BL bufchk(); - - V mg_buffer(AtomList &l) { if(buf && buf->Symbol()) { l(1); SetSymbol(l[0],buf->Symbol()); } else l(); } - inline V ms_buffer(const AtomList &l) { m_set(l.Count(),l.Atoms()); } - - inline V mg_min(F &v) const { v = curmin*s2u; } - inline V mg_max(F &v) const { v = curmax*s2u; } + static void arrmul(int n,const t_sample *in,t_sample *out,t_sample mul) { flext::MulSamples(out,in,mul,n); } + inline void arrmul(int n,const t_sample *in,t_sample *out) const { arrmul(n,in,out,(t_sample)(1.f/s2u)); } + + void mg_buffer(AtomList &l) { if(buf.Symbol()) { l(1); SetSymbol(l[0],buf.Symbol()); } } + inline void ms_buffer(const AtomList &l) { m_set(l.Count(),l.Atoms()); } + + inline void mg_min(float &v) const { v = curmin*s2u; } + inline void mg_max(float &v) const { v = curmax*s2u; } + + void Refresh() { if(update && !Initing()) { DoUpdate(update); update = xsc__; } } + void Update(unsigned int f,bool refr = false) { update |= f; if(refr) Refresh(); } + + //! return 0...invalid, 1...changed, -1...unchanged + int ChkBuffer(bool refr = false); + + typedef flext::buffer::lock_t lock_t; + + //! Lock buffer (buffer must be checked ok) + lock_t Lock() { return buf.Lock(); } + //! Unlock buffer (buffer must be checked ok) + void Unlock(lock_t l) { buf.Unlock(l); } + + void ResetRange() + { + curmin = 0; + curmax = buf.Frames(); + Update(xsc_range); + } + + virtual void DoReset(); + virtual void DoUpdate(unsigned int flags); + + virtual void m_loadbang(); + virtual void m_print() = 0; + virtual void m_dsp(int n,t_sample *const *insigs,t_sample *const *outsigs); private: - static V setup(t_classid c); - FLEXT_CALLBACK(m_start) - FLEXT_CALLBACK(m_stop) + unsigned int update; + + static void setup(t_classid c); FLEXT_CALLBACK_V(m_set) FLEXT_CALLBACK(m_print) @@ -206,25 +280,25 @@ protected: #endif #define DEFSIGFUN(NAME) \ - static V st_##NAME(thisType *obj,I n,S *const *in,S *const *out) { obj->NAME (n,in,out); } \ - V NAME(I n,S *const *in,S *const *out) + static void st_##NAME(thisType *obj,int n,t_sample *const *in,t_sample *const *out) { obj->NAME (n,in,out); } \ + void NAME(int n,t_sample *const *in,t_sample *const *out) #define TMPLSIGFUN(NAME) \ - TMPLDEF static V st_##NAME(thisType *obj,I n,S *const *in,S *const *out) { obj->NAME TMPLCALL (n,in,out); } \ - TMPLDEF V NAME(I n,S *const *in,S *const *out) + TMPLDEF static void st_##NAME(thisType *obj,int n,t_sample *const *in,t_sample *const *out) { obj->NAME TMPLCALL (n,in,out); } \ + TMPLDEF void NAME(int n,t_sample *const *in,t_sample *const *out) - #define TMPLSTFUN(NAME) TMPLDEF static V NAME(const S *bdt,const I smin,const I smax,const I n,const I inchns,const I outchns,S *const *invecs,S *const *outvecs) + #define TMPLSTFUN(NAME) TMPLDEF static void NAME(const t_sample *bdt,const int smin,const int smax,const int n,const int inchns,const int outchns,t_sample *const *invecs,t_sample *const *outvecs) #define SETSIGFUN(VAR,FUN) v_##VAR = FUN #define SETSTFUN(VAR,FUN) VAR = FUN #define DEFSIGCALL(NAME) \ - inline V NAME(I n,S *const *in,S *const *out) { (*v_##NAME)(this,n,in,out); } \ - V (*v_##NAME)(thisType *obj,I n,S *const *in,S *const *out) + inline void NAME(int n,t_sample *const *in,t_sample *const *out) { (*v_##NAME)(this,n,in,out); } \ + void (*v_##NAME)(thisType *obj,int n,t_sample *const *in,t_sample *const *out) #define DEFSTCALL(NAME) \ - V (*NAME)(const S *bdt,const I smin,const I smax,const I n,const I inchns,const I outchns,S *const *invecs,S *const *outvecs) + void (*NAME)(const t_sample *bdt,const int smin,const int smax,const int n,const int inchns,const int outchns,t_sample *const *invecs,t_sample *const *outvecs) #else #ifdef TMPLOPT @@ -241,20 +315,20 @@ protected: #define TMPLSTF(FUN,BCHNS,IOCHNS) TMPLFUN(FUN,BCHNS,IOCHNS) - #define DEFSIGFUN(NAME) V NAME(I n,S *const *in,S *const *out) - #define TMPLSIGFUN(NAME) TMPLDEF V NAME(I n,S *const *in,S *const *out) - #define TMPLSTFUN(NAME) TMPLDEF static V NAME(const S *bdt,const I smin,const I smax,const I n,const I inchns,const I outchns,S *const *invecs,S *const *outvecs) + #define DEFSIGFUN(NAME) void NAME(int n,t_sample *const *in,t_sample *const *out) + #define TMPLSIGFUN(NAME) TMPLDEF void NAME(int n,t_sample *const *in,t_sample *const *out) + #define TMPLSTFUN(NAME) TMPLDEF static void NAME(const t_sample *bdt,const int smin,const int smax,const int n,const int inchns,const int outchns,t_sample *const *invecs,t_sample *const *outvecs,bool looped) #define SETSIGFUN(VAR,FUN) v_##VAR = FUN #define DEFSIGCALL(NAME) \ - inline V NAME(I n,S *const *in,S *const *out) { (this->*v_##NAME)(n,in,out); } \ - V (thisType::*v_##NAME)(I n,S *const *invecs,S *const *outvecs) + inline void NAME(int n,t_sample *const *in,t_sample *const *out) { (this->*v_##NAME)(n,in,out); } \ + void (thisType::*v_##NAME)(int n,t_sample *const *invecs,t_sample *const *outvecs) #define SETSTFUN(VAR,FUN) VAR = FUN #define DEFSTCALL(NAME) \ - V (*NAME)(const S *bdt,const I smin,const I smax,const I n,const I inchns,const I outchns,S *const *invecs,S *const *outvecs) + void (*NAME)(const t_sample *bdt,const int smin,const int smax,const int n,const int inchns,const int outchns,t_sample *const *invecs,t_sample *const *outvecs,bool looped) #endif @@ -269,18 +343,18 @@ protected: #ifdef TMPLOPT // optimization by using constants for channel numbers #define SIGCHNS(BCHNS,bchns,IOCHNS,iochns) \ - const I BCHNS = _BCHNS_ < 0?(bchns):_BCHNS_; \ - const I IOCHNS = _IOCHNS_ < 0?MIN(iochns,BCHNS):MIN(_IOCHNS_,BCHNS) + const int BCHNS = _BCHNS_ < 0?(bchns):_BCHNS_; \ + const int IOCHNS = _IOCHNS_ < 0?MIN(iochns,BCHNS):MIN(_IOCHNS_,BCHNS) #else // no template optimization #if FLEXT_SYS == FLEXT_SYS_PD // only mono buffers #define SIGCHNS(BCHNS,bchns,IOCHNS,iochns) \ - const I BCHNS = 1; \ - const I IOCHNS = MIN(iochns,BCHNS) + const int BCHNS = 1; \ + const int IOCHNS = MIN(iochns,BCHNS) #else // MAXMSP #define SIGCHNS(BCHNS,bchns,IOCHNS,iochns) \ - const I BCHNS = bchns; \ - const I IOCHNS = MIN(iochns,BCHNS) + const int BCHNS = bchns; \ + const int IOCHNS = MIN(iochns,BCHNS) #endif #endif @@ -291,19 +365,42 @@ class xinter: FLEXT_HEADER_S(xinter,xsample,setup) public: - xinter(): outchns(1),doplay(false),interp(xsi_4p) {} - -protected: - virtual I m_set(I argc,const t_atom *argv); - virtual V m_start(); - virtual V m_stop(); + enum xs_loop { + xsl_once = 0,xsl_loop,xsl_bidir + }; + + xinter() + : outchns(1),doplay(false) + , interp(xsi_4p),loopmode(xsl_loop) + {} + + void m_start() + { + ChkBuffer(); + doplay = true; + Update(xsc_startstop,true); + } + + void m_stop() + { + ChkBuffer(); + doplay = false; + Update(xsc_startstop,true); + } + + void m_interp(xs_intp mode) + { + interp = mode; + Update(xsc_intp,true); + } - inline V m_interp(xs_intp mode = xsi__) { interp = mode; s_dsp(); } +protected: - I outchns; - BL doplay; + int outchns; + bool doplay; xs_intp interp; + xs_loop loopmode; TMPLSIGFUN(s_play0); TMPLSIGFUN(s_play1); @@ -318,13 +415,18 @@ protected: DEFSIGCALL(playfun); DEFSIGCALL(zerofun); - virtual V s_dsp(); + virtual void DoUpdate(unsigned int flags); -private: - static V setup(t_classid c); + FLEXT_CALLBACK(m_start) + FLEXT_CALLBACK(m_stop) FLEXT_CALLSET_E(m_interp,xs_intp) FLEXT_ATTRGET_E(interp,xs_intp) + + FLEXT_ATTRGET_E(loopmode,xs_loop) + +private: + static void setup(t_classid c); }; #ifdef TMPLOPT @@ -332,5 +434,3 @@ private: #endif #endif - - |