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 #ifdef FLEXT_USE_CMEM
125 #if !defined(_MSC_VER) && !defined(__BORLANDC__)
126 #define NEWTHROW throw(std::bad_alloc)
127 #define DELTHROW throw()
134 void *
operator new(
size_t bytes)
NEWTHROW;
135 void operator delete(
void *blk)
DELTHROW;
136 #ifndef __MRC__ // doesn't allow new[] overloading?!
137 void *
operator new[](
size_t bytes)
NEWTHROW;
138 void operator delete[](
void *blk)
DELTHROW;
141 #endif // FLEXT_USE_CMEM
180 static int Version();
183 static const char *VersionStr();
189 typedef t_float Float;
191 typedef t_sample Sample;
192 typedef const t_symbol *Symbol;
208 #if FLEXT_SYS == FLEXT_SYS_PD
210 #elif FLEXT_SYS == FLEXT_SYS_MAX
213 #error Not implemented
218 #if FLEXT_SYS == FLEXT_SYS_PD
219 # if PD_MINOR_VERSION >= 41
221 # define FLEXT_PD_ARRAYGRAB garray_getfloatwords
222 # define FLEXT_ARRAYTYPE t_word
223 # define FLEXT_GETSAMPLE(x) ((x).w_float)
224 # define _FLEXT_NEED_SAMPLE_CONV 1
228 # define FLEXT_PD_ARRAYGRAB garray_getfloatarray
229 # define FLEXT_ARRAYTYPE t_sample
230 # define FLEXT_GETSAMPLE(x) (x)
231 # define _FLEXT_NEED_SAMPLE_CONV 0
234 #elif FLEXT_SYS == FLEXT_SYS_MAX
235 # define FLEXT_ARRAYTYPE float
236 # define FLEXT_GETSAMPLE(x) (x)
237 # define _FLEXT_NEED_SAMPLE_CONV 0
243 Element(FLEXT_ARRAYTYPE s): el(s) {}
244 operator FLEXT_ARRAYTYPE &() {
return el; }
245 operator FLEXT_ARRAYTYPE ()
const {
return el; }
246 #if _FLEXT_NEED_SAMPLE_CONV
247 Element(t_sample s) { FLEXT_GETSAMPLE(el) = s; }
248 operator t_sample &() {
return FLEXT_GETSAMPLE(el); }
249 operator t_sample ()
const {
return FLEXT_GETSAMPLE(el); }
260 buffer(
const t_symbol *s = NULL,
bool delayed =
false);
271 #if FLEXT_SYS == FLEXT_SYS_PD
283 #if FLEXT_SYS == FLEXT_SYS_PD
285 #elif FLEXT_SYS == FLEXT_SYS_MAX
286 const t_buffer *p = (
const t_buffer *)sym->s_thing;
287 return p && p->b_valid;
289 #error not implemented
308 void Unlock(lock_t prv);
314 int Set(
const t_symbol *s = NULL,
bool nameonly =
false);
319 void Dirty(
bool refr =
false);
327 bool IsDirty()
const;
330 const t_symbol *Symbol()
const {
return sym; }
333 const char *Name()
const {
return sym?GetString(sym):
""; }
338 Element *Data() {
return data; }
340 const Element *Data()
const {
return data; }
343 int Channels()
const {
return chns; }
345 int Frames()
const {
return frames; }
347 void Frames(
int fr,
bool keep =
false,
bool zero =
true);
350 inline Element operator [](
int index)
const {
return data[index]; }
353 inline Element &operator [](
int index) {
return data[index]; }
356 void SetRefrIntv(
float intv);
362 Locker(buffer &b): buf(b),lock(b.Lock()) {}
363 ~Locker() { buf.Unlock(lock); }
378 #if FLEXT_SYS == FLEXT_SYS_PD
394 static void cb_tick(buffer *b);
395 #elif FLEXT_SYS == FLEXT_SYS_MAX
410 static void CopyAtom(t_atom *dst,
const t_atom *src) { *dst = *src; }
414 static void CopyAtoms(
int cnt,t_atom *dst,
const t_atom *src);
417 static bool PrintAtom(
const t_atom &a,
char *buf,
size_t bufsz);
422 static const char *ScanAtom(t_atom &a,
const char *buf);
425 static t_atom *CopyList(
int argc,
const t_atom *argv);
428 static bool PrintList(
int argc,
const t_atom *argv,
char *buf,
size_t bufsz);
435 static int ScanList(
int argc,t_atom *argv,
const char *buf);
438 static void CopyMem(
void *dst,
const void *src,
int bytes);
440 static void CopySamples(t_sample *dst,
const t_sample *src,
int cnt);
441 template<
typename T>
static void CopySamples(T *dst,
const T *src,
int cnt) { CopyMem(dst,src,
sizeof(*src)*cnt); }
443 static void ZeroMem(
void *dst,
int bytes);
445 static void SetSamples(t_sample *dst,
int cnt,t_sample s);
446 template<
typename T>
static void SetSamples(T *dst,
int cnt,t_sample s) {
for(
int i = 0; i < cnt; ++i) dst[i] = s; }
448 static void ZeroSamples(t_sample *dst,
int cnt) { SetSamples(dst,cnt,0); }
449 template<
typename T>
static void ZeroSamples(T *dst,
int cnt) { ZeroMem(dst,
sizeof(*dst)*cnt); }
453 static unsigned long AtomHash(
const t_atom &a);
463 static const t_symbol *sym__;
466 static const t_symbol *sym_float;
468 static const t_symbol *sym_symbol;
470 static const t_symbol *sym_bang;
472 static const t_symbol *sym_list;
474 static const t_symbol *sym_anything;
479 static const t_symbol *sym_int;
484 static const t_symbol *sym_pointer;
487 static const t_symbol *sym_signal;
490 static const t_symbol *MakeSymbol(
const t_symbol *s) {
return s; }
493 static const t_symbol *MakeSymbol(
const char *s) { return ::gensym(
const_cast<char *
>(s)); }
495 static const char *GetString(
const t_symbol *s) {
return s->s_name; }
497 static const char *GetAString(
const t_symbol *s,
const char *def = NULL) {
return s?GetString(s):def; }
502 static void SetAtom(t_atom &a,
const t_atom &b) { CopyAtom(&a,&b); }
504 static int CmpAtom(
const t_atom &a,
const t_atom &b);
509 static int GetType(
const t_atom &a) {
return a.a_type; }
512 static bool IsNothing(
const t_atom &a) {
return a.a_type == A_NULL; }
514 static void SetNothing(t_atom &a) { a.a_type = A_NULL; }
517 static bool IsFloat(
const t_atom &a) {
return a.a_type == A_FLOAT; }
520 static bool CanbeFloat(
const t_atom &a) {
return IsFloat(a) || IsInt(a); }
523 static float GetFloat(
const t_atom &a) {
return a.a_w.w_float; }
525 static void SetFloat(t_atom &a,
float v) { a.a_type = A_FLOAT; a.a_w.w_float = v; }
528 static bool IsSymbol(
const t_atom &a) {
return a.a_type == A_SYMBOL; }
530 #if FLEXT_SYS == FLEXT_SYS_PD
531 static const t_symbol *GetSymbol(
const t_atom &a) {
return const_cast<const t_symbol *
>(a.a_w.w_symbol); }
534 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); }
535 #elif FLEXT_SYS == FLEXT_SYS_MAX
536 static const t_symbol *GetSymbol(
const t_atom &a) {
return const_cast<const t_symbol *
>(a.a_w.w_sym); }
539 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); }
543 static const t_symbol *GetASymbol(
const t_atom &a,
const t_symbol *def = NULL) {
return IsSymbol(a)?GetSymbol(a):def; }
547 static bool IsString(
const t_atom &a) {
return IsSymbol(a); }
549 static const char *GetString(
const t_atom &a) {
const t_symbol *s = GetSymbol(a);
return s?GetString(s):NULL; }
551 static const char *GetAString(
const t_atom &a,
const char *def = NULL) {
return IsSymbol(a)?GetAString(GetSymbol(a),def):def; }
553 static void GetAString(
const t_atom &a,
char *buf,
size_t szbuf);
555 static void SetString(t_atom &a,
const char *c) { SetSymbol(a,MakeSymbol(c)); }
558 static bool CanbeInt(
const t_atom &a) {
return IsFloat(a) || IsInt(a); }
560 #if FLEXT_SYS == FLEXT_SYS_PD
561 static float GetAFloat(
const t_atom &a,
float def = 0) {
return IsFloat(a)?GetFloat(a):def; }
565 static bool IsInt(
const t_atom &) {
return false; }
567 static int GetInt(
const t_atom &a) {
return (
int)GetFloat(a); }
569 static int GetAInt(
const t_atom &a,
int def = 0) {
return (
int)GetAFloat(a,(
float)def); }
571 static void SetInt(t_atom &a,
int v) { a.a_type = A_FLOAT; a.a_w.w_float = (float)v; }
573 #ifndef FLEXT_COMPATIBLE
574 static bool IsPointer(
const t_atom &a) {
return a.a_type == A_POINTER; }
577 static bool CanbePointer(
const t_atom &a) {
return IsPointer(a); }
579 static t_gpointer *GetPointer(
const t_atom &a) {
return a.a_w.w_gpointer; }
581 static t_gpointer *GetAPointer(
const t_atom &a,t_gpointer *def = NULL) {
return IsPointer(a)?GetPointer(a):def; }
583 static void SetPointer(t_atom &a,t_gpointer *p) { a.a_type = A_POINTER; a.a_w.w_gpointer = (t_gpointer *)p; }
586 #elif FLEXT_SYS == FLEXT_SYS_MAX
587 static float GetAFloat(
const t_atom &a,
float def = 0) {
return IsFloat(a)?GetFloat(a):(IsInt(a)?GetInt(a):def); }
591 static bool IsInt(
const t_atom &a) {
return a.a_type == A_INT; }
593 static int GetInt(
const t_atom &a) {
return a.a_w.w_long; }
595 static int GetAInt(
const t_atom &a,
int def = 0) {
return IsInt(a)?GetInt(a):(IsFloat(a)?(int)GetFloat(a):def); }
597 static void SetInt(t_atom &a,
int v) { a.a_type = A_INT; a.a_w.w_long = v; }
599 #error "Platform not supported"
605 static void SetBool(t_atom &a,
bool v) { SetInt(a,v?1:0); }
607 static bool CanbeBool(
const t_atom &a) {
return CanbeInt(a); }
609 static bool GetABool(
const t_atom &a) {
return GetAInt(a) != 0; }
611 static bool GetBool(
const t_atom &a) {
return GetInt(a) != 0; }
621 AtomList(): cnt(0),lst(NULL) {}
623 explicit AtomList(
int argc,
const t_atom *argv = NULL): cnt(0),lst(NULL) { operator()(argc,argv); }
625 AtomList(
const AtomList &a): cnt(0),lst(NULL) { operator =(a); }
630 AtomList &Clear() {
return operator()(); }
633 AtomList &Set(
int argc,
const t_atom *argv,
int offs = 0,
bool resize =
false);
635 int Get(t_atom *argv,
int mxsz = -1)
const;
638 AtomList &operator()(
int argc = 0,
const t_atom *argv = NULL) {
return Set(argc,argv,0,
true); }
640 AtomList &operator =(
const AtomList &a) {
return operator()(a.Count(),a.Atoms()); }
643 int Compare(
const AtomList &a)
const;
645 bool operator <(
const AtomList &a)
const {
return Compare(a) < 0; }
646 bool operator <=(
const AtomList &a)
const {
return Compare(a) <= 0; }
647 bool operator >(
const AtomList &a)
const {
return Compare(a) > 0; }
648 bool operator >=(
const AtomList &a)
const {
return Compare(a) >= 0; }
649 bool operator ==(
const AtomList &a)
const {
return Compare(a) == 0; }
650 bool operator !=(
const AtomList &a)
const {
return Compare(a) != 0; }
653 int Count()
const {
return cnt; }
655 t_atom &operator [](
int ix) {
return lst[ix]; }
657 const t_atom &operator [](
int ix)
const {
return lst[ix]; }
660 t_atom *Atoms() {
return lst; }
662 const t_atom *Atoms()
const {
return lst; }
665 AtomList &Append(
int argc,
const t_atom *argv = NULL)
674 AtomList &Prepend(
int argc,
const t_atom *argv = NULL)
677 Alloc(c+argc,0,c,argc);
683 AtomList &Append(
const t_atom &a) {
return Append(1,&a); }
685 AtomList &Append(
const AtomList &a) {
return Append(a.Count(),a.Atoms()); }
687 AtomList &Prepend(
const t_atom &a) {
return Prepend(1,&a); }
689 AtomList &Prepend(
const AtomList &a) {
return Prepend(a.Count(),a.Atoms()); }
692 void GetPart(
int offs,
int len,AtomList &ret)
const;
694 AtomList &Part(
int offs,
int len) { GetPart(offs,len,*
this);
return *
this; }
697 bool Print(
char *buffer,
int buflen)
const {
return flext::PrintList(Count(),Atoms(),buffer,buflen); }
702 int Scan(
const char *buffer) {
return flext::ScanList(Count(),Atoms(),buffer); }
705 virtual void Alloc(
int sz,
int keepix = -1,
int keeplen = -1,
int keepto = 0);
716 explicit AtomListStaticBase(
int pc,t_atom *dt): precnt(pc),predata(dt) {}
717 virtual ~AtomListStaticBase();
718 virtual void Alloc(
int sz,
int keepix = -1,
int keeplen = -1,
int keepto = 0);
721 AtomListStaticBase &operator =(
const AtomList &a) { AtomList::operator =(a);
return *
this; }
722 AtomListStaticBase &operator =(
const AtomListStaticBase &a) { AtomList::operator =(a);
return *
this; }
725 t_atom *
const predata;
730 :
public AtomListStaticBase
734 explicit AtomListStatic(): AtomListStaticBase(PRE,pre) {}
736 explicit AtomListStatic(
int argc,
const t_atom *argv = NULL): AtomListStaticBase(PRE,pre) { AtomList::operator()(argc,argv); }
738 explicit AtomListStatic(
const AtomList &a): AtomListStaticBase(PRE,pre) { operator =(a); }
741 AtomListStatic &operator =(
const AtomList &a) { AtomListStaticBase::operator =(a);
return *
this; }
742 AtomListStatic &operator =(
const AtomListStatic &a) { AtomListStaticBase::operator =(a);
return *
this; }
752 explicit AtomAnything(): hdr(NULL) {}
755 explicit AtomAnything(
const t_symbol *h,
int argc = 0,
const t_atom *argv = NULL)
756 : AtomList(argc,argv),hdr(h?h:sym__)
760 explicit AtomAnything(
const char *h,
int argc = 0,
const t_atom *argv = NULL)
761 : AtomList(argc,argv),hdr(MakeSymbol(h))
765 AtomAnything(
const AtomAnything &a)
766 : AtomList(a),hdr(a.hdr)
770 AtomAnything &Clear() {
return operator()(); }
773 const t_symbol *Header()
const {
return hdr; }
776 void Header(
const t_symbol *h) { hdr = h; }
779 AtomAnything &operator()(
const t_symbol *h = NULL,
int argc = 0,
const t_atom *argv = NULL)
781 hdr = h; AtomList::operator()(argc,argv);
786 AtomAnything &operator =(
const AtomAnything &a) {
return operator()(a.Header(),a.Count(),a.Atoms()); }
796 #pragma optimize("p",off) // improve floating point precision consistency
798 static t_atom *SetDouble(t_atom *dbl,
double d)
800 float f =
static_cast<float>(d);
801 float r =
static_cast<float>(d-f);
807 #pragma optimize("p",on)
810 static double GetDouble(
int argc,
const t_atom *argv)
812 double d = argc >= 1?GetAFloat(argv[0]):0;
813 return argc >= 2?d+GetAFloat(argv[1]):d;
816 static AtomList &SetDouble(AtomList &l,
double d) { SetDouble(l(2).Atoms(),d);
return l; }
818 static double GetDouble(
const AtomList &l) {
return GetDouble(l.Count(),l.Atoms()); }
832 static MsgBundle *MsgNew();
835 static void MsgFree(MsgBundle *mb);
838 static void ToSysMsg(MsgBundle *mb);
841 static void ToOutMsg(MsgBundle *mb);
844 static void ToQueueMsg(MsgBundle *mb);
853 static bool Forward(
const t_symbol *sym,
const t_symbol *s,
int argc,
const t_atom *argv);
854 static bool Forward(
const t_symbol *sym,
const AtomAnything &args) {
return Forward(sym,args.Header(),args.Count(),args.Atoms()); }
855 static bool Forward(
const char *sym,
const AtomAnything &args) {
return Forward(MakeSymbol(sym),args.Header(),args.Count(),args.Atoms()); }
856 static bool Forward(
const t_symbol *sym,
int argc,
const t_atom *argv) {
return Forward(sym,sym_list,argc,argv); }
857 static bool Forward(
const t_symbol *sym,
const AtomList &args) {
return Forward(sym,args.Count(),args.Atoms()); }
858 static bool Forward(
const char *sym,
const AtomList &args) {
return Forward(MakeSymbol(sym),args.Count(),args.Atoms()); }
860 static bool SysForward(
const t_symbol *sym,
const t_symbol *s,
int argc,
const t_atom *argv);
861 static bool SysForward(
const t_symbol *sym,
const AtomAnything &args) {
return SysForward(sym,args.Header(),args.Count(),args.Atoms()); }
862 static bool SysForward(
const char *sym,
const AtomAnything &args) {
return SysForward(MakeSymbol(sym),args.Header(),args.Count(),args.Atoms()); }
863 static bool SysForward(
const t_symbol *sym,
int argc,
const t_atom *argv) {
return SysForward(sym,sym_list,argc,argv); }
864 static bool SysForward(
const t_symbol *sym,
const AtomList &args) {
return SysForward(sym,args.Count(),args.Atoms()); }
865 static bool SysForward(
const char *sym,
const AtomList &args) {
return SysForward(MakeSymbol(sym),args.Count(),args.Atoms()); }
867 static bool QueueForward(
const t_symbol *sym,
const t_symbol *s,
int argc,
const t_atom *argv);
868 static bool QueueForward(
const t_symbol *sym,
const AtomAnything &args) {
return QueueForward(sym,args.Header(),args.Count(),args.Atoms()); }
869 static bool QueueForward(
const char *sym,
const AtomAnything &args) {
return QueueForward(MakeSymbol(sym),args.Header(),args.Count(),args.Atoms()); }
870 static bool QueueForward(
const t_symbol *sym,
int argc,
const t_atom *argv) {
return QueueForward(sym,sym_list,argc,argv); }
871 static bool QueueForward(
const t_symbol *sym,
const AtomList &args) {
return QueueForward(sym,args.Count(),args.Atoms()); }
872 static bool QueueForward(
const char *sym,
const AtomList &args) {
return QueueForward(MakeSymbol(sym),args.Count(),args.Atoms()); }
874 static bool MsgForward(MsgBundle *mb,
const t_symbol *sym,
const t_symbol *s,
int argc,
const t_atom *argv);
875 static bool MsgForward(MsgBundle *mb,
const t_symbol *sym,
const AtomAnything &args) {
return MsgForward(mb,sym,args.Header(),args.Count(),args.Atoms()); }
876 static bool MsgForward(MsgBundle *mb,
const char *sym,
const AtomAnything &args) {
return MsgForward(mb,MakeSymbol(sym),args.Header(),args.Count(),args.Atoms()); }
877 static bool MsgForward(MsgBundle *mb,
const t_symbol *sym,
int argc,
const t_atom *argv) {
return MsgForward(mb,sym,sym_list,argc,argv); }
878 static bool MsgForward(MsgBundle *mb,
const t_symbol *sym,
const AtomList &args) {
return MsgForward(mb,sym,args.Count(),args.Atoms()); }
879 static bool MsgForward(MsgBundle *mb,
const char *sym,
const AtomList &args) {
return MsgForward(mb,MakeSymbol(sym),args.Count(),args.Atoms()); }
891 #if FLEXT_SYS == FLEXT_SYS_PD
892 #if PD_MINOR_VERSION >= 38 || (PD_MINOR_VERSION >= 37 && defined(PD_DEVEL_VERSION))
893 static void Lock() { sys_lock(); }
894 static void Unlock() { sys_unlock(); }
897 static void Lock() {}
898 static void Unlock() {}
900 #elif FLEXT_SYS == FLEXT_SYS_MAX
902 static void Lock() { critical_enter(0); }
903 static void Unlock() { critical_exit(0); }
916 static bool IsThreadRegistered();
918 static bool IsThreadRegistered() {
return false; }
924 # if FLEXT_THREADS == FLEXT_THR_MP
925 typedef MPTaskID thrid_t;
926 # elif FLEXT_THREADS == FLEXT_THR_POSIX
927 typedef pthread_t thrid_t;
928 # elif FLEXT_THREADS == FLEXT_THR_WIN32
929 typedef DWORD thrid_t;
931 # error Threading model not supported
936 static thrid_t GetThreadId() {
937 #if FLEXT_THREADS == FLEXT_THR_POSIX
938 return pthread_self();
939 #elif FLEXT_THREADS == FLEXT_THR_MP
940 return MPCurrentTaskID();
941 #elif FLEXT_THREADS == FLEXT_THR_WIN32
942 return GetCurrentThreadId();
950 static thrid_t GetSysThreadId() {
return thrid; }
953 static bool ShouldExit();
956 static bool IsThread(thrid_t t,thrid_t ref = GetThreadId()) {
957 #if FLEXT_THREADS == FLEXT_THR_POSIX
958 return pthread_equal(ref,t) != 0;
972 thr_params(
int n = 1): cl(NULL),var(new _data[n]) {}
973 ~thr_params() {
delete[] var; }
975 void set_any(
const t_symbol *s,
int argc,
const t_atom *argv) { var[0]._any =
new AtomAnything(s,argc,argv); }
976 void set_list(
int argc,
const t_atom *argv) { var[0]._list =
new AtomList(argc,argv); }
992 static thrid_t thrhelpid;
993 static thrid_t thrmsgid;
994 static void ThrHelper(
void *);
997 static thrid_t thrid;
1000 static bool StartHelper();
1007 static void ThrYield() {
1008 #if FLEXT_THREADS == FLEXT_THR_POSIX
1011 #elif FLEXT_THREADS == FLEXT_THR_MP
1013 #elif FLEXT_THREADS == FLEXT_THR_WIN32
1022 static bool IsThreadPreemptive(thrid_t t = GetThreadId()) {
1023 #if FLEXT_THREADS == FLEXT_THR_POSIX || FLEXT_THREADS == FLEXT_THR_WIN32
1025 #elif FLEXT_THREADS == FLEXT_THR_MP
1026 return MPTaskIsPreemptive(t);
1035 static bool RelPriority(
int dp,thrid_t ref = GetSysThreadId(),thrid_t thr = GetThreadId());
1039 static int GetPriority(thrid_t thr = GetThreadId());
1043 static bool SetPriority(
int p,thrid_t thr = GetThreadId());
1050 #if FLEXT_THREADS == FLEXT_THR_POSIX
1054 ThrMutex() { pthread_mutex_init(&mutex,NULL); }
1056 ~ThrMutex() { pthread_mutex_destroy(&mutex); }
1059 bool Lock() {
return pthread_mutex_lock(&mutex) == 0; }
1065 bool TryLock() {
return pthread_mutex_trylock(&mutex) == 0; }
1067 bool Unlock() {
return pthread_mutex_unlock(&mutex) == 0; }
1070 pthread_mutex_t mutex;
1073 #elif FLEXT_THREADS == FLEXT_THR_WIN32
1077 ThrMutex() { ::InitializeCriticalSection(&mutex); }
1079 ~ThrMutex() { ::DeleteCriticalSection(&mutex); }
1082 bool Lock() { ::EnterCriticalSection(&mutex);
return true; }
1088 bool TryLock() { return ::TryEnterCriticalSection(&mutex) != 0; }
1090 bool Unlock() { ::LeaveCriticalSection(&mutex);
return true; }
1093 CRITICAL_SECTION mutex;
1095 #elif FLEXT_THREADS == FLEXT_THR_MP
1099 ThrMutex() { MPCreateCriticalRegion(&crit); }
1101 ~ThrMutex() { MPDeleteCriticalRegion(crit); }
1104 bool Lock() {
return MPEnterCriticalRegion(crit,kDurationForever) == noErr; }
1108 bool TryLock() {
return MPEnterCriticalRegion(crit,kDurationImmediate) == noErr; }
1110 bool Unlock() {
return MPExitCriticalRegion(crit) == noErr; }
1113 MPCriticalRegionID crit;
1116 #error "Not implemented"
1128 ThrCond() { pthread_cond_init(&cond,NULL); }
1130 ~ThrCond() { pthread_cond_destroy(&cond); }
1141 bool TimedWait(
double ftime);
1144 bool Signal() {
return pthread_cond_signal(&cond) == 0; }
1147 pthread_cond_t cond;
1149 #elif FLEXT_THREADS == FLEXT_THR_WIN32
1153 ThrCond() { cond = CreateEvent(NULL,FALSE,FALSE,NULL); }
1155 ~ThrCond() { CloseHandle(cond); }
1158 bool Wait() {
return WaitForSingleObject(cond,INFINITE) == WAIT_OBJECT_0; }
1166 bool TimedWait(
double ftime) {
return WaitForSingleObject(cond,(LONG)(ftime*1000)) == WAIT_OBJECT_0; }
1169 bool Signal() {
return SetEvent(cond) != 0; }
1174 #elif FLEXT_THREADS == FLEXT_THR_MP
1178 ThrCond() { MPCreateEvent(&ev); }
1180 ~ThrCond() { MPDeleteEvent(ev); }
1183 bool Wait() {
return MPWaitForEvent(ev,NULL,kDurationForever) == noErr; }
1188 bool TimedWait(
double tm) {
return MPWaitForEvent(ev,NULL,tm*kDurationMicrosecond*1.e6) == noErr; }
1191 bool Signal() {
return MPSetEvent(ev,1) == noErr; }
1197 #error "Not implemented"
1206 static bool PushThread();
1212 static void PopThread();
1220 static bool LaunchThread(
void (*meth)(thr_params *p),thr_params *params = NULL);
1229 static bool StopThread(
void (*meth)(thr_params *p),thr_params *params = NULL,
bool wait =
false);
1233 static void RegisterThread(thrid_t
id = GetThreadId());
1236 static void UnregisterThread(thrid_t
id = GetThreadId());
1238 #endif // FLEXT_THREADS
1258 static double GetTime()
1260 #if FLEXT_SYS == FLEXT_SYS_PD
1261 return clock_gettimesince(0)*0.001;
1262 #elif FLEXT_SYS == FLEXT_SYS_MAX
1264 clock_getftime(&tm);
1267 #error Not implemented
1274 static double GetTimeGrain()
1276 #if FLEXT_SYS == FLEXT_SYS_PD
1278 #elif FLEXT_SYS == FLEXT_SYS_MAX
1281 #error Not implemented
1287 static double GetOSTime();
1293 static void Sleep(
double s);
1302 Timer(
bool queued =
false);
1306 void SetCallback(
void (*cb)(
void *data)) { clss = NULL,cback = cb; }
1313 bool At(
double time,
void *data = NULL,
bool dopast =
true);
1315 bool Delay(
double time,
void *data = NULL);
1317 bool Periodic(
double time,
void *data = NULL);
1319 bool Now(
void *data = NULL) {
return Delay(0,data); }
1322 virtual void Work();
1325 static void callback(Timer *tmr);
1327 #if FLEXT_SYS == FLEXT_SYS_PD
1329 #elif FLEXT_SYS == FLEXT_SYS_MAX
1330 static void queuefun(Timer *tmr);
1334 #error Not implemented
1338 void (*cback)(
void *data);
1347 static bool InDSP() {
return indsp; }
1364 static unsigned long GetSIMDCapabilities();
1367 static void MulSamples(t_sample *dst,
const t_sample *src,t_sample mul,
int cnt);
1368 static void MulSamples(t_sample *dst,
const t_sample *src,
const t_sample *mul,
int cnt);
1369 static void AddSamples(t_sample *dst,
const t_sample *src,t_sample add,
int cnt);
1370 static void AddSamples(t_sample *dst,
const t_sample *src,
const t_sample *add,
int cnt);
1371 static void ScaleSamples(t_sample *dst,
const t_sample *src,t_sample mul,t_sample add,
int cnt);
1372 static void ScaleSamples(t_sample *dst,
const t_sample *src,t_sample mul,
const t_sample *add,
int cnt);
1373 static void ScaleSamples(t_sample *dst,
const t_sample *src,
const t_sample *mul,
const t_sample *add,
int cnt);
1382 friend class flext_obj;
1385 static void Setup();
1387 static bool chktilde(
const char *objname);
1389 static unsigned long simdcaps;
1391 static const t_symbol *sym_attributes;
1392 static const t_symbol *sym_methods;
1394 #if FLEXT_SYS == FLEXT_SYS_MAX
1395 static const t_symbol *sym_buffer;
1396 static const t_symbol *sym_size;
1397 static const t_symbol *sym_dirty;
1406 inline bool operator ==(
const t_atom &a,
const t_atom &b) {
return flext::CmpAtom(a,b) == 0; }
1407 inline bool operator !=(
const t_atom &a,
const t_atom &b) {
return flext::CmpAtom(a,b) != 0; }
1408 inline bool operator <(
const t_atom &a,
const t_atom &b) {
return flext::CmpAtom(a,b) < 0; }
1409 inline bool operator <=(
const t_atom &a,
const t_atom &b) {
return flext::CmpAtom(a,b) <= 0; }
1410 inline bool operator >(
const t_atom &a,
const t_atom &b) {
return flext::CmpAtom(a,b) > 0; }
1411 inline bool operator >=(
const t_atom &a,
const t_atom &b) {
return flext::CmpAtom(a,b) >= 0; }