aboutsummaryrefslogtreecommitdiff
path: root/externals/grill/vasp/source/buflib.cpp
diff options
context:
space:
mode:
authorThomas Grill <xovo@users.sourceforge.net>2002-12-02 19:21:08 +0000
committerThomas Grill <xovo@users.sourceforge.net>2002-12-02 19:21:08 +0000
commit9815096db22c73cacdbb65512d1b61d633db7fa8 (patch)
tree4a6582ead85b8efd031f68e717fbc8a5b3a3df3f /externals/grill/vasp/source/buflib.cpp
parent0a109da279e9df66fb5ea7d6bdaeffed16592f02 (diff)
"version 0.1.1"
svn path=/trunk/; revision=267
Diffstat (limited to 'externals/grill/vasp/source/buflib.cpp')
-rw-r--r--externals/grill/vasp/source/buflib.cpp258
1 files changed, 258 insertions, 0 deletions
diff --git a/externals/grill/vasp/source/buflib.cpp b/externals/grill/vasp/source/buflib.cpp
new file mode 100644
index 00000000..30b500c4
--- /dev/null
+++ b/externals/grill/vasp/source/buflib.cpp
@@ -0,0 +1,258 @@
+/*
+
+VASP modular - vector assembling signal processor / objects for Max/MSP and PD
+
+Copyright (c) 2002 Thomas Grill (xovo@gmx.net)
+For information on usage and redistribution, and for a DISCLAIMER OF ALL
+WARRANTIES, see the file, "license.txt," in this distribution.
+
+*/
+
+#include "buflib.h"
+#include <stdio.h>
+
+#define LIBTICK 100 // tick time in ms
+#define LIBTOL 2 // how many ticks till release
+
+#define REUSE_MAXLOSEREL 0.1 // max. fraction of lost buffer size
+#define REUSE_MAXLOSEABS 10000 // max. lost buffer size
+
+#define LIBMAGIC 12349876L // magic number for s_thing data check
+
+
+class FreeEntry
+{
+public:
+ FreeEntry(t_symbol *s): sym(s),nxt(NULL) {}
+
+ t_symbol *sym;
+ FreeEntry *nxt;
+};
+
+class BufEntry
+{
+public:
+ BufEntry(t_symbol *s,I fr);
+ ~BufEntry();
+
+ V IncRef();
+ V DecRef();
+
+// UL magic;
+ t_symbol *sym;
+ I refcnt,tick;
+ BufEntry *nxt;
+
+ I alloc,len;
+ S *data;
+};
+
+
+static BufEntry *libhead = NULL,*libtail = NULL;
+static FreeEntry *freehead = NULL,*freetail = NULL;
+static I libcnt = 0,libtick = 0;
+static t_clock *libclk = NULL;
+
+#ifdef FLEXT_THREADS
+static flext::ThrMutex libmtx;
+#endif
+
+static V FreeLibSym(t_symbol *s);
+
+
+
+
+BufEntry::BufEntry(t_symbol *s,I fr):
+ sym(s), //magic(LIBMAGIC),
+ alloc(fr),len(fr),data(new S[fr]),
+ refcnt(0),nxt(NULL)
+{
+// ASSERT(!flext_base::GetThing(sym));
+// flext_base::SetThing(sym,this);
+}
+
+BufEntry::~BufEntry()
+{
+ if(sym) FreeLibSym(sym);
+ if(data) delete[] data;
+}
+
+V BufEntry::IncRef() { ++refcnt; }
+V BufEntry::DecRef() { --refcnt; tick = libtick; }
+
+static BufEntry *FindInLib(const t_symbol *s)
+{
+ BufEntry *e;
+ for(e = libhead; e && e->sym != s; e = e->nxt) (void)0;
+ return e?e:NULL;
+}
+
+VBuffer *BufLib::Get(const VSymbol &s,I chn,I len,I offs)
+{
+ BufEntry *e = FindInLib(s.Symbol());
+ if(e)
+ return new ImmBuf(e,len,offs);
+ else
+ return new SysBuf(s,chn,len,offs);
+}
+
+V BufLib::IncRef(t_symbol *s)
+{
+ if(s) {
+ BufEntry *e = FindInLib(s);
+ if(e) e->IncRef();
+ }
+}
+
+V BufLib::DecRef(t_symbol *s)
+{
+ if(s) {
+ BufEntry *e = FindInLib(s);
+ if(e) e->DecRef();
+ }
+}
+
+static t_symbol *GetLibSym()
+{
+ if(freehead) {
+ // reuse from free-list
+ FreeEntry *r = freehead;
+ freehead = r->nxt;
+ if(!freehead) freetail = NULL;
+ t_symbol *s = r->sym;
+ delete r;
+ return s;
+ }
+ else {
+ // allocate new symbol
+ char tmp[20];
+ #ifdef __MWERKS__
+ std::
+ #endif
+ sprintf(tmp,"vasp!%04i",libcnt); // what if libcnt has > 4 digits?
+ libcnt++;
+ return gensym(tmp);
+ }
+
+ clock_delay(libclk,LIBTICK);
+}
+
+static V FreeLibSym(t_symbol *sym)
+{
+ FreeEntry *f = new FreeEntry(sym);
+ if(!freehead) freehead = f;
+ else freetail->nxt = f;
+ freetail = f;
+}
+
+static V LibTick(V *)
+{
+#ifdef FLEXT_THREADS
+ libmtx.Lock();
+#endif
+
+ // collect garbage
+ BufEntry *e,*p;
+ for(p = NULL,e = libhead; e; ) {
+ if(e->refcnt <= 0 && e->tick+LIBTOL < libtick) {
+ ASSERT(e->refcnt == 0);
+
+ BufEntry *n = e->nxt;
+
+ if(p) p->nxt = n;
+ else libhead = n;
+
+ if(!n) libtail = p;
+ else e->nxt = NULL;
+
+ delete e;
+
+ e = n;
+ }
+ else
+ p = e,e = e->nxt;
+ }
+
+ ++libtick;
+ clock_delay(libclk,LIBTICK);
+
+#ifdef FLEXT_THREADS
+ libmtx.Unlock();
+#endif
+}
+
+BufEntry *BufLib::NewImm(I fr)
+{
+ if(!libclk) {
+ libclk = (t_clock *)clock_new(NULL,(t_method)LibTick);
+ clock_delay(libclk,LIBTICK);
+ }
+
+ t_symbol *s = NULL;
+// do {
+ s = GetLibSym();
+// } while(s->s_thing);
+
+ BufEntry *entry = new BufEntry(s,fr);
+
+#ifdef FLEXT_THREADS
+ libmtx.Lock();
+#endif
+
+ if(libtail) libtail->nxt = entry;
+ else libhead = entry;
+ libtail = entry;
+
+#ifdef FLEXT_THREADS
+ libmtx.Unlock();
+#endif
+
+ return entry;
+}
+
+static F reuse_maxloserel = (F)REUSE_MAXLOSEREL;
+static I reuse_maxloseabs = REUSE_MAXLOSEABS;
+
+BufEntry *BufLib::Resize(BufEntry *e,I fr,BL keep)
+{
+ if(e->alloc >= fr && fr >= e->alloc*(1-reuse_maxloserel) && fr >= (e->alloc-reuse_maxloseabs)) {
+ // reuse buffer
+ e->len = fr;
+ }
+ else {
+ S *nd = new S[fr];
+ if(keep) {
+ I l = fr;
+ if(e->len < l) l = e->len;
+ flext::CopyMem(e->data,nd,l);
+ }
+
+ delete[] e->data;
+ e->data = nd;
+ e->len = e->alloc = fr;
+ }
+ return e;
+}
+
+
+
+ImmBuf::ImmBuf(I len):
+ VBuffer(0,len),
+ entry(BufLib::NewImm(len))
+{}
+
+ImmBuf::ImmBuf(BufEntry *e,I len,I offs):
+ VBuffer(0,len,offs),
+ entry(e)
+{}
+
+VSymbol ImmBuf::Symbol() const { return entry->sym; }
+
+I ImmBuf::Frames() const { return entry->len; }
+
+V ImmBuf::Frames(I fr,BL keep) { entry = BufLib::Resize(entry,fr,keep); }
+
+S *ImmBuf::Data() { return entry->data; }
+
+
+