23 #if C74_MAX_SDK_VERSION >= 0x0610
48 static void post(
const char *fmt,...);
50 static void error(
const char *fmt,...);
58 #ifdef FLEXT_NOGLOBALNEW
59 #error FLEXT_NOGLOBALNEW is deprecated, define FLEXT_USE_CMEM instead
60 #define FLEXT_USE_CMEM
64 inline void *
operator new(
size_t bytes) { return ::operator
new(bytes); }
65 inline void operator delete(
void *blk) { ::operator
delete(blk); }
67 inline void *
operator new[](
size_t bytes) { return ::operator
new[](bytes); }
68 inline void operator delete[](
void *blk) { ::operator
delete[](blk); }
70 static bool MemCheck(
void *) {
return true; }
76 void *
operator new(
size_t bytes);
78 void operator delete(
void *blk);
80 #ifndef __MRC__ // doesn't allow new[] overloading?!
81 inline void *
operator new[](
size_t bytes) {
return operator new(bytes); }
82 inline void operator delete[](
void *blk) {
operator delete(blk); }
86 static bool MemCheck(
void *blk);
88 static bool MemCheck(
void *) {
return true; }
94 inline void *
operator new(size_t,
void *p) {
return p; }
95 inline void operator delete(
void *,
void *) {}
97 inline void *
operator new[](size_t,
void *p) {
return p; }
98 inline void operator delete[](
void *,
void *) {}
103 static void *NewAligned(
size_t bytes,
int bitalign = 128);
106 static T *NewAligned(
size_t times,
int bitalign = 128) {
return static_cast<T *>(NewAligned(times*
sizeof(T),bitalign)); }
108 static void FreeAligned(
void *blk);
110 static bool IsAligned(
void *ptr,
int bitalign = 128) {
111 return (reinterpret_cast<size_t>(ptr)&(bitalign-1)) == 0;
116 #ifndef FLEXT_USE_CMEM
121 #if !defined(_MSC_VER) && !defined(__BORLANDC__)
122 #define NEWTHROW throw(std::bad_alloc)
123 #define DELTHROW throw()
130 inline void *
operator new(
size_t bytes)
NEWTHROW {
return flext_root::operator
new(bytes); }
131 inline void operator delete(
void *blk)
DELTHROW { flext_root::operator
delete(blk); }
132 #ifndef __MRC__ // doesn't allow new[] overloading?!
133 inline void *
operator new[](
size_t bytes)
NEWTHROW {
return flext_root::operator
new[](bytes); }
134 inline void operator delete[](
void *blk)
DELTHROW { flext_root::operator
delete[](blk); }
137 #endif // FLEXT_USE_CMEM
176 static int Version();
179 static const char *VersionStr();
185 typedef t_float Float;
187 typedef t_sample Sample;
188 typedef const t_symbol *Symbol;
204 #if FLEXT_SYS == FLEXT_SYS_PD
206 #elif FLEXT_SYS == FLEXT_SYS_MAX
209 #error Not implemented
214 #if FLEXT_SYS == FLEXT_SYS_PD
215 # if PD_MINOR_VERSION >= 41
217 # define FLEXT_PD_ARRAYGRAB garray_getfloatwords
218 # define FLEXT_ARRAYTYPE t_word
219 # define FLEXT_GETSAMPLE(x) ((x).w_float)
223 # define FLEXT_PD_ARRAYGRAB garray_getfloatarray
224 # define FLEXT_ARRAYTYPE t_sample
225 # define FLEXT_GETSAMPLE(x) (x)
228 #elif FLEXT_SYS == FLEXT_SYS_MAX
229 # define FLEXT_ARRAYTYPE t_sample
230 # define FLEXT_GETSAMPLE(x) (x)
236 Element(t_sample s) { FLEXT_GETSAMPLE(el) = s; }
237 operator t_sample &() {
return FLEXT_GETSAMPLE(el); }
238 operator t_sample ()
const {
return FLEXT_GETSAMPLE(el); }
248 buffer(
const t_symbol *s = NULL,
bool delayed =
false);
259 #if FLEXT_SYS == FLEXT_SYS_PD
271 #if FLEXT_SYS == FLEXT_SYS_PD
273 #elif FLEXT_SYS == FLEXT_SYS_MAX
274 const t_buffer *p = (
const t_buffer *)sym->s_thing;
275 return p && p->b_valid;
277 #error not implemented
296 void Unlock(lock_t prv);
302 int Set(
const t_symbol *s = NULL,
bool nameonly =
false);
307 void Dirty(
bool refr =
false);
315 bool IsDirty()
const;
318 const t_symbol *Symbol()
const {
return sym; }
321 const char *Name()
const {
return sym?GetString(sym):
""; }
326 Element *Data() {
return data; }
328 const Element *Data()
const {
return data; }
331 int Channels()
const {
return chns; }
333 int Frames()
const {
return frames; }
335 void Frames(
int fr,
bool keep =
false,
bool zero =
true);
338 inline t_sample operator [](
int index)
const {
return data[index]; }
341 inline t_sample &operator [](
int index) {
return data[index]; }
344 void SetRefrIntv(
float intv);
350 Locker(buffer &b): buf(b),lock(b.Lock()) {}
351 ~Locker() { buf.Unlock(lock); }
366 #if FLEXT_SYS == FLEXT_SYS_PD
382 static void cb_tick(buffer *b);
383 #elif FLEXT_SYS == FLEXT_SYS_MAX
398 static void CopyAtom(t_atom *dst,
const t_atom *src) { *dst = *src; }
402 static void CopyAtoms(
int cnt,t_atom *dst,
const t_atom *src);
405 static bool PrintAtom(
const t_atom &a,
char *buf,
size_t bufsz);
410 static const char *ScanAtom(t_atom &a,
const char *buf);
413 static t_atom *CopyList(
int argc,
const t_atom *argv);
416 static bool PrintList(
int argc,
const t_atom *argv,
char *buf,
size_t bufsz);
423 static int ScanList(
int argc,t_atom *argv,
const char *buf);
426 static void CopyMem(
void *dst,
const void *src,
int bytes);
428 static void CopySamples(t_sample *dst,
const t_sample *src,
int cnt);
429 template<
typename T>
static void CopySamples(T *dst,
const T *src,
int cnt) { CopyMem(dst,src,
sizeof(*src)*cnt); }
431 static void ZeroMem(
void *dst,
int bytes);
433 static void SetSamples(t_sample *dst,
int cnt,t_sample s);
434 template<
typename T>
static void SetSamples(T *dst,
int cnt,t_sample s) {
for(
int i = 0; i < cnt; ++i) dst[i] = s; }
436 static void ZeroSamples(t_sample *dst,
int cnt) { SetSamples(dst,cnt,0); }
437 template<
typename T>
static void ZeroSamples(T *dst,
int cnt) { ZeroMem(dst,
sizeof(*dst)*cnt); }
441 static unsigned long AtomHash(
const t_atom &a);
451 static const t_symbol *sym__;
454 static const t_symbol *sym_float;
456 static const t_symbol *sym_symbol;
458 static const t_symbol *sym_bang;
460 static const t_symbol *sym_list;
462 static const t_symbol *sym_anything;
467 static const t_symbol *sym_int;
472 static const t_symbol *sym_pointer;
475 static const t_symbol *sym_signal;
478 static const t_symbol *MakeSymbol(
const t_symbol *s) {
return s; }
481 static const t_symbol *MakeSymbol(
const char *s) { return ::gensym(const_cast<char *>(s)); }
483 static const char *GetString(
const t_symbol *s) {
return s->s_name; }
485 static const char *GetAString(
const t_symbol *s,
const char *def = NULL) {
return s?GetString(s):def; }
490 static void SetAtom(t_atom &a,
const t_atom &b) { CopyAtom(&a,&b); }
492 static int CmpAtom(
const t_atom &a,
const t_atom &b);
497 static int GetType(
const t_atom &a) {
return a.a_type; }
500 static bool IsNothing(
const t_atom &a) {
return a.a_type == A_NULL; }
502 static void SetNothing(t_atom &a) { a.a_type = A_NULL; }
505 static bool IsFloat(
const t_atom &a) {
return a.a_type == A_FLOAT; }
508 static bool CanbeFloat(
const t_atom &a) {
return IsFloat(a) || IsInt(a); }
511 static float GetFloat(
const t_atom &a) {
return a.a_w.w_float; }
513 static void SetFloat(t_atom &a,
float v) { a.a_type = A_FLOAT; a.a_w.w_float = v; }
516 static bool IsSymbol(
const t_atom &a) {
return a.a_type == A_SYMBOL; }
518 #if FLEXT_SYS == FLEXT_SYS_PD
519 static const t_symbol *GetSymbol(
const t_atom &a) {
return const_cast<const t_symbol *>(a.a_w.w_symbol); }
522 static void SetSymbol(t_atom &a,
const t_symbol *s) { a.a_type = A_SYMBOL; a.a_w.w_symbol = const_cast<t_symbol *>(s); }
523 #elif FLEXT_SYS == FLEXT_SYS_MAX
524 static const t_symbol *GetSymbol(
const t_atom &a) {
return const_cast<const t_symbol *>(a.a_w.w_sym); }
527 static void SetSymbol(t_atom &a,
const t_symbol *s) { a.a_type = A_SYMBOL; a.a_w.w_sym = const_cast<t_symbol *>(s); }
531 static const t_symbol *GetASymbol(
const t_atom &a,
const t_symbol *def = NULL) {
return IsSymbol(a)?GetSymbol(a):def; }
535 static bool IsString(
const t_atom &a) {
return IsSymbol(a); }
537 static const char *GetString(
const t_atom &a) {
const t_symbol *s = GetSymbol(a);
return s?GetString(s):NULL; }
539 static const char *GetAString(
const t_atom &a,
const char *def = NULL) {
return IsSymbol(a)?GetAString(GetSymbol(a),def):def; }
541 static void GetAString(
const t_atom &a,
char *buf,
size_t szbuf);
543 static void SetString(t_atom &a,
const char *c) { SetSymbol(a,MakeSymbol(c)); }
546 static bool CanbeInt(
const t_atom &a) {
return IsFloat(a) || IsInt(a); }
548 #if FLEXT_SYS == FLEXT_SYS_PD
549 static float GetAFloat(
const t_atom &a,
float def = 0) {
return IsFloat(a)?GetFloat(a):def; }
553 static bool IsInt(
const t_atom &) {
return false; }
555 static int GetInt(
const t_atom &a) {
return (
int)GetFloat(a); }
557 static int GetAInt(
const t_atom &a,
int def = 0) {
return (
int)GetAFloat(a,(
float)def); }
559 static void SetInt(t_atom &a,
int v) { a.a_type = A_FLOAT; a.a_w.w_float = (float)v; }
561 #ifndef FLEXT_COMPATIBLE
562 static bool IsPointer(
const t_atom &a) {
return a.a_type == A_POINTER; }
565 static bool CanbePointer(
const t_atom &a) {
return IsPointer(a); }
567 static t_gpointer *GetPointer(
const t_atom &a) {
return a.a_w.w_gpointer; }
569 static t_gpointer *GetAPointer(
const t_atom &a,t_gpointer *def = NULL) {
return IsPointer(a)?GetPointer(a):def; }
571 static void SetPointer(t_atom &a,t_gpointer *p) { a.a_type = A_POINTER; a.a_w.w_gpointer = (t_gpointer *)p; }
574 #elif FLEXT_SYS == FLEXT_SYS_MAX
575 static float GetAFloat(
const t_atom &a,
float def = 0) {
return IsFloat(a)?GetFloat(a):(IsInt(a)?GetInt(a):def); }
579 static bool IsInt(
const t_atom &a) {
return a.a_type == A_INT; }
581 static int GetInt(
const t_atom &a) {
return a.a_w.w_long; }
583 static int GetAInt(
const t_atom &a,
int def = 0) {
return IsInt(a)?GetInt(a):(IsFloat(a)?(int)GetFloat(a):def); }
585 static void SetInt(t_atom &a,
int v) { a.a_type = A_INT; a.a_w.w_long = v; }
587 #error "Platform not supported"
593 static void SetBool(t_atom &a,
bool v) { SetInt(a,v?1:0); }
595 static bool CanbeBool(
const t_atom &a) {
return CanbeInt(a); }
597 static bool GetABool(
const t_atom &a) {
return GetAInt(a) != 0; }
599 static bool GetBool(
const t_atom &a) {
return GetInt(a) != 0; }
609 AtomList(): cnt(0),lst(NULL) {}
611 explicit AtomList(
int argc,
const t_atom *argv = NULL): cnt(0),lst(NULL) { operator()(argc,argv); }
613 AtomList(
const AtomList &a): cnt(0),lst(NULL) { operator =(a); }
618 AtomList &Clear() {
return operator()(); }
621 AtomList &Set(
int argc,
const t_atom *argv,
int offs = 0,
bool resize =
false);
623 int Get(t_atom *argv,
int mxsz = -1)
const;
626 AtomList &operator()(
int argc = 0,
const t_atom *argv = NULL) {
return Set(argc,argv,0,
true); }
628 AtomList &operator =(
const AtomList &a) {
return operator()(a.Count(),a.Atoms()); }
631 int Compare(
const AtomList &a)
const;
633 bool operator <(
const AtomList &a)
const {
return Compare(a) < 0; }
634 bool operator <=(
const AtomList &a)
const {
return Compare(a) <= 0; }
635 bool operator >(
const AtomList &a)
const {
return Compare(a) > 0; }
636 bool operator >=(
const AtomList &a)
const {
return Compare(a) >= 0; }
637 bool operator ==(
const AtomList &a)
const {
return Compare(a) == 0; }
638 bool operator !=(
const AtomList &a)
const {
return Compare(a) != 0; }
641 int Count()
const {
return cnt; }
643 t_atom &operator [](
int ix) {
return lst[ix]; }
645 const t_atom &operator [](
int ix)
const {
return lst[ix]; }
648 t_atom *Atoms() {
return lst; }
650 const t_atom *Atoms()
const {
return lst; }
653 AtomList &Append(
int argc,
const t_atom *argv = NULL)
662 AtomList &Prepend(
int argc,
const t_atom *argv = NULL)
665 Alloc(c+argc,0,c,argc);
671 AtomList &Append(
const t_atom &a) {
return Append(1,&a); }
673 AtomList &Append(
const AtomList &a) {
return Append(a.Count(),a.Atoms()); }
675 AtomList &Prepend(
const t_atom &a) {
return Prepend(1,&a); }
677 AtomList &Prepend(
const AtomList &a) {
return Prepend(a.Count(),a.Atoms()); }
680 void GetPart(
int offs,
int len,AtomList &ret)
const;
682 AtomList &Part(
int offs,
int len) { GetPart(offs,len,*
this);
return *
this; }
685 bool Print(
char *buffer,
int buflen)
const {
return flext::PrintList(Count(),Atoms(),buffer,buflen); }
690 int Scan(
const char *buffer) {
return flext::ScanList(Count(),Atoms(),buffer); }
693 virtual void Alloc(
int sz,
int keepix = -1,
int keeplen = -1,
int keepto = 0);
704 explicit AtomListStaticBase(
int pc,t_atom *dt): precnt(pc),predata(dt) {}
705 virtual ~AtomListStaticBase();
706 virtual void Alloc(
int sz,
int keepix = -1,
int keeplen = -1,
int keepto = 0);
709 AtomListStaticBase &operator =(
const AtomList &a) { AtomList::operator =(a);
return *
this; }
710 AtomListStaticBase &operator =(
const AtomListStaticBase &a) { AtomList::operator =(a);
return *
this; }
713 t_atom *
const predata;
718 :
public AtomListStaticBase
722 explicit AtomListStatic(): AtomListStaticBase(PRE,pre) {}
724 explicit AtomListStatic(
int argc,
const t_atom *argv = NULL): AtomListStaticBase(PRE,pre) { AtomList::operator()(argc,argv); }
726 explicit AtomListStatic(
const AtomList &a): AtomListStaticBase(PRE,pre) { operator =(a); }
729 AtomListStatic &operator =(
const AtomList &a) { AtomListStaticBase::operator =(a);
return *
this; }
730 AtomListStatic &operator =(
const AtomListStatic &a) { AtomListStaticBase::operator =(a);
return *
this; }
740 explicit AtomAnything(): hdr(NULL) {}
743 explicit AtomAnything(
const t_symbol *h,
int argc = 0,
const t_atom *argv = NULL)
744 : AtomList(argc,argv),hdr(h?h:sym__)
748 explicit AtomAnything(
const char *h,
int argc = 0,
const t_atom *argv = NULL)
749 : AtomList(argc,argv),hdr(MakeSymbol(h))
753 AtomAnything(
const AtomAnything &a)
754 : AtomList(a),hdr(a.hdr)
758 AtomAnything &Clear() {
return operator()(); }
761 const t_symbol *Header()
const {
return hdr; }
764 void Header(
const t_symbol *h) { hdr = h; }
767 AtomAnything &operator()(
const t_symbol *h = NULL,
int argc = 0,
const t_atom *argv = NULL)
769 hdr = h; AtomList::operator()(argc,argv);
774 AtomAnything &operator =(
const AtomAnything &a) {
return operator()(a.Header(),a.Count(),a.Atoms()); }
784 #pragma optimize("p",off) // improve floating point precision consistency
786 static t_atom *SetDouble(t_atom *dbl,
double d)
788 float f = static_cast<float>(d);
789 float r = static_cast<float>(d-f);
795 #pragma optimize("p",on)
798 static double GetDouble(
int argc,
const t_atom *argv)
800 double d = argc >= 1?GetAFloat(argv[0]):0;
801 return argc >= 2?d+GetAFloat(argv[1]):d;
804 static AtomList &SetDouble(AtomList &l,
double d) { SetDouble(l(2).Atoms(),d);
return l; }
806 static double GetDouble(
const AtomList &l) {
return GetDouble(l.Count(),l.Atoms()); }
820 static MsgBundle *MsgNew();
823 static void MsgFree(MsgBundle *mb);
826 static void ToSysMsg(MsgBundle *mb);
829 static void ToOutMsg(MsgBundle *mb);
832 static void ToQueueMsg(MsgBundle *mb);
841 static bool Forward(
const t_symbol *sym,
const t_symbol *s,
int argc,
const t_atom *argv);
842 static bool Forward(
const t_symbol *sym,
const AtomAnything &args) {
return Forward(sym,args.Header(),args.Count(),args.Atoms()); }
843 static bool Forward(
const char *sym,
const AtomAnything &args) {
return Forward(MakeSymbol(sym),args.Header(),args.Count(),args.Atoms()); }
844 static bool Forward(
const t_symbol *sym,
int argc,
const t_atom *argv) {
return Forward(sym,sym_list,argc,argv); }
845 static bool Forward(
const t_symbol *sym,
const AtomList &args) {
return Forward(sym,args.Count(),args.Atoms()); }
846 static bool Forward(
const char *sym,
const AtomList &args) {
return Forward(MakeSymbol(sym),args.Count(),args.Atoms()); }
848 static bool SysForward(
const t_symbol *sym,
const t_symbol *s,
int argc,
const t_atom *argv);
849 static bool SysForward(
const t_symbol *sym,
const AtomAnything &args) {
return SysForward(sym,args.Header(),args.Count(),args.Atoms()); }
850 static bool SysForward(
const char *sym,
const AtomAnything &args) {
return SysForward(MakeSymbol(sym),args.Header(),args.Count(),args.Atoms()); }
851 static bool SysForward(
const t_symbol *sym,
int argc,
const t_atom *argv) {
return SysForward(sym,sym_list,argc,argv); }
852 static bool SysForward(
const t_symbol *sym,
const AtomList &args) {
return SysForward(sym,args.Count(),args.Atoms()); }
853 static bool SysForward(
const char *sym,
const AtomList &args) {
return SysForward(MakeSymbol(sym),args.Count(),args.Atoms()); }
855 static bool QueueForward(
const t_symbol *sym,
const t_symbol *s,
int argc,
const t_atom *argv);
856 static bool QueueForward(
const t_symbol *sym,
const AtomAnything &args) {
return QueueForward(sym,args.Header(),args.Count(),args.Atoms()); }
857 static bool QueueForward(
const char *sym,
const AtomAnything &args) {
return QueueForward(MakeSymbol(sym),args.Header(),args.Count(),args.Atoms()); }
858 static bool QueueForward(
const t_symbol *sym,
int argc,
const t_atom *argv) {
return QueueForward(sym,sym_list,argc,argv); }
859 static bool QueueForward(
const t_symbol *sym,
const AtomList &args) {
return QueueForward(sym,args.Count(),args.Atoms()); }
860 static bool QueueForward(
const char *sym,
const AtomList &args) {
return QueueForward(MakeSymbol(sym),args.Count(),args.Atoms()); }
862 static bool MsgForward(MsgBundle *mb,
const t_symbol *sym,
const t_symbol *s,
int argc,
const t_atom *argv);
863 static bool MsgForward(MsgBundle *mb,
const t_symbol *sym,
const AtomAnything &args) {
return MsgForward(mb,sym,args.Header(),args.Count(),args.Atoms()); }
864 static bool MsgForward(MsgBundle *mb,
const char *sym,
const AtomAnything &args) {
return MsgForward(mb,MakeSymbol(sym),args.Header(),args.Count(),args.Atoms()); }
865 static bool MsgForward(MsgBundle *mb,
const t_symbol *sym,
int argc,
const t_atom *argv) {
return MsgForward(mb,sym,sym_list,argc,argv); }
866 static bool MsgForward(MsgBundle *mb,
const t_symbol *sym,
const AtomList &args) {
return MsgForward(mb,sym,args.Count(),args.Atoms()); }
867 static bool MsgForward(MsgBundle *mb,
const char *sym,
const AtomList &args) {
return MsgForward(mb,MakeSymbol(sym),args.Count(),args.Atoms()); }
879 #if FLEXT_SYS == FLEXT_SYS_PD
880 #if PD_MINOR_VERSION >= 38 || (PD_MINOR_VERSION >= 37 && defined(PD_DEVEL_VERSION))
881 static void Lock() { sys_lock(); }
882 static void Unlock() { sys_unlock(); }
885 static void Lock() {}
886 static void Unlock() {}
888 #elif FLEXT_SYS == FLEXT_SYS_MAX
890 static void Lock() { critical_enter(0); }
891 static void Unlock() { critical_exit(0); }
904 static bool IsThreadRegistered();
906 static bool IsThreadRegistered() {
return false; }
912 # if FLEXT_THREADS == FLEXT_THR_MP
913 typedef MPTaskID thrid_t;
914 # elif FLEXT_THREADS == FLEXT_THR_POSIX
915 typedef pthread_t thrid_t;
916 # elif FLEXT_THREADS == FLEXT_THR_WIN32
917 typedef DWORD thrid_t;
919 # error Threading model not supported
924 static thrid_t GetThreadId() {
925 #if FLEXT_THREADS == FLEXT_THR_POSIX
926 return pthread_self();
927 #elif FLEXT_THREADS == FLEXT_THR_MP
928 return MPCurrentTaskID();
929 #elif FLEXT_THREADS == FLEXT_THR_WIN32
930 return GetCurrentThreadId();
938 static thrid_t GetSysThreadId() {
return thrid; }
941 static bool ShouldExit();
944 static bool IsThread(thrid_t t,thrid_t ref = GetThreadId()) {
945 #if FLEXT_THREADS == FLEXT_THR_POSIX
946 return pthread_equal(ref,t) != 0;
960 thr_params(
int n = 1): cl(NULL),var(new _data[n]) {}
961 ~thr_params() {
delete[] var; }
963 void set_any(
const t_symbol *s,
int argc,
const t_atom *argv) { var[0]._any =
new AtomAnything(s,argc,argv); }
964 void set_list(
int argc,
const t_atom *argv) { var[0]._list =
new AtomList(argc,argv); }
980 static thrid_t thrhelpid;
981 static thrid_t thrmsgid;
982 static void ThrHelper(
void *);
985 static thrid_t thrid;
988 static bool StartHelper();
995 static void ThrYield() {
996 #if FLEXT_THREADS == FLEXT_THR_POSIX
999 #elif FLEXT_THREADS == FLEXT_THR_MP
1001 #elif FLEXT_THREADS == FLEXT_THR_WIN32
1010 static bool IsThreadPreemptive(thrid_t t = GetThreadId()) {
1011 #if FLEXT_THREADS == FLEXT_THR_POSIX || FLEXT_THREADS == FLEXT_THR_WIN32
1013 #elif FLEXT_THREADS == FLEXT_THR_MP
1014 return MPTaskIsPreemptive(t);
1023 static bool RelPriority(
int dp,thrid_t ref = GetSysThreadId(),thrid_t thr = GetThreadId());
1027 static int GetPriority(thrid_t thr = GetThreadId());
1031 static bool SetPriority(
int p,thrid_t thr = GetThreadId());
1038 #if FLEXT_THREADS == FLEXT_THR_POSIX
1042 ThrMutex() { pthread_mutex_init(&mutex,NULL); }
1044 ~ThrMutex() { pthread_mutex_destroy(&mutex); }
1047 bool Lock() {
return pthread_mutex_lock(&mutex) == 0; }
1053 bool TryLock() {
return pthread_mutex_trylock(&mutex) == 0; }
1055 bool Unlock() {
return pthread_mutex_unlock(&mutex) == 0; }
1058 pthread_mutex_t mutex;
1061 #elif FLEXT_THREADS == FLEXT_THR_WIN32
1065 ThrMutex() { ::InitializeCriticalSection(&mutex); }
1067 ~ThrMutex() { ::DeleteCriticalSection(&mutex); }
1070 bool Lock() { ::EnterCriticalSection(&mutex);
return true; }
1076 bool TryLock() { return ::TryEnterCriticalSection(&mutex) != 0; }
1078 bool Unlock() { ::LeaveCriticalSection(&mutex);
return true; }
1081 CRITICAL_SECTION mutex;
1083 #elif FLEXT_THREADS == FLEXT_THR_MP
1087 ThrMutex() { MPCreateCriticalRegion(&crit); }
1089 ~ThrMutex() { MPDeleteCriticalRegion(crit); }
1092 bool Lock() {
return MPEnterCriticalRegion(crit,kDurationForever) == noErr; }
1096 bool TryLock() {
return MPEnterCriticalRegion(crit,kDurationImmediate) == noErr; }
1098 bool Unlock() {
return MPExitCriticalRegion(crit) == noErr; }
1101 MPCriticalRegionID crit;
1104 #error "Not implemented"
1116 ThrCond() { pthread_cond_init(&cond,NULL); }
1118 ~ThrCond() { pthread_cond_destroy(&cond); }
1129 bool TimedWait(
double ftime);
1132 bool Signal() {
return pthread_cond_signal(&cond) == 0; }
1135 pthread_cond_t cond;
1137 #elif FLEXT_THREADS == FLEXT_THR_WIN32
1141 ThrCond() { cond = CreateEvent(NULL,FALSE,FALSE,NULL); }
1143 ~ThrCond() { CloseHandle(cond); }
1146 bool Wait() {
return WaitForSingleObject(cond,INFINITE) == WAIT_OBJECT_0; }
1154 bool TimedWait(
double ftime) {
return WaitForSingleObject(cond,(LONG)(ftime*1000)) == WAIT_OBJECT_0; }
1157 bool Signal() {
return SetEvent(cond) != 0; }
1162 #elif FLEXT_THREADS == FLEXT_THR_MP
1166 ThrCond() { MPCreateEvent(&ev); }
1168 ~ThrCond() { MPDeleteEvent(ev); }
1171 bool Wait() {
return MPWaitForEvent(ev,NULL,kDurationForever) == noErr; }
1176 bool TimedWait(
double tm) {
return MPWaitForEvent(ev,NULL,tm*kDurationMicrosecond*1.e6) == noErr; }
1179 bool Signal() {
return MPSetEvent(ev,1) == noErr; }
1185 #error "Not implemented"
1194 static bool PushThread();
1200 static void PopThread();
1208 static bool LaunchThread(
void (*meth)(thr_params *p),thr_params *params = NULL);
1217 static bool StopThread(
void (*meth)(thr_params *p),thr_params *params = NULL,
bool wait =
false);
1221 static void RegisterThread(thrid_t
id = GetThreadId());
1224 static void UnregisterThread(thrid_t
id = GetThreadId());
1226 #endif // FLEXT_THREADS
1246 static double GetTime()
1248 #if FLEXT_SYS == FLEXT_SYS_PD
1249 return clock_gettimesince(0)*0.001;
1250 #elif FLEXT_SYS == FLEXT_SYS_MAX
1252 clock_getftime(&tm);
1255 #error Not implemented
1262 static double GetTimeGrain()
1264 #if FLEXT_SYS == FLEXT_SYS_PD
1266 #elif FLEXT_SYS == FLEXT_SYS_MAX
1269 #error Not implemented
1275 static double GetOSTime();
1281 static void Sleep(
double s);
1290 Timer(
bool queued =
false);
1294 void SetCallback(
void (*cb)(
void *data)) { clss = NULL,cback = cb; }
1301 bool At(
double time,
void *data = NULL,
bool dopast =
true);
1303 bool Delay(
double time,
void *data = NULL);
1305 bool Periodic(
double time,
void *data = NULL);
1307 bool Now(
void *data = NULL) {
return Delay(0,data); }
1310 virtual void Work();
1313 static void callback(Timer *tmr);
1315 #if FLEXT_SYS == FLEXT_SYS_PD
1317 #elif FLEXT_SYS == FLEXT_SYS_MAX
1318 static void queuefun(Timer *tmr);
1322 #error Not implemented
1326 void (*cback)(
void *data);
1335 static bool InDSP() {
return indsp; }
1352 static unsigned long GetSIMDCapabilities();
1355 static void MulSamples(t_sample *dst,
const t_sample *src,t_sample mul,
int cnt);
1356 static void MulSamples(t_sample *dst,
const t_sample *src,
const t_sample *mul,
int cnt);
1357 static void AddSamples(t_sample *dst,
const t_sample *src,t_sample add,
int cnt);
1358 static void AddSamples(t_sample *dst,
const t_sample *src,
const t_sample *add,
int cnt);
1359 static void ScaleSamples(t_sample *dst,
const t_sample *src,t_sample mul,t_sample add,
int cnt);
1360 static void ScaleSamples(t_sample *dst,
const t_sample *src,t_sample mul,
const t_sample *add,
int cnt);
1361 static void ScaleSamples(t_sample *dst,
const t_sample *src,
const t_sample *mul,
const t_sample *add,
int cnt);
1370 friend class flext_obj;
1373 static void Setup();
1375 static bool chktilde(
const char *objname);
1377 static unsigned long simdcaps;
1379 static const t_symbol *sym_attributes;
1380 static const t_symbol *sym_methods;
1382 #if FLEXT_SYS == FLEXT_SYS_MAX
1383 static const t_symbol *sym_buffer;
1384 static const t_symbol *sym_size;
1385 static const t_symbol *sym_dirty;
1394 inline bool operator ==(
const t_atom &a,
const t_atom &b) {
return flext::CmpAtom(a,b) == 0; }
1395 inline bool operator !=(
const t_atom &a,
const t_atom &b) {
return flext::CmpAtom(a,b) != 0; }
1396 inline bool operator <(
const t_atom &a,
const t_atom &b) {
return flext::CmpAtom(a,b) < 0; }
1397 inline bool operator <=(
const t_atom &a,
const t_atom &b) {
return flext::CmpAtom(a,b) <= 0; }
1398 inline bool operator >(
const t_atom &a,
const t_atom &b) {
return flext::CmpAtom(a,b) > 0; }
1399 inline bool operator >=(
const t_atom &a,
const t_atom &b) {
return flext::CmpAtom(a,b) >= 0; }