aboutsummaryrefslogtreecommitdiff
path: root/externals/grill
diff options
context:
space:
mode:
authorThomas Grill <xovo@users.sourceforge.net>2003-02-26 04:40:35 +0000
committerThomas Grill <xovo@users.sourceforge.net>2003-02-26 04:40:35 +0000
commitf128374bfd1869bde1f22d4f80b6267c99b507a7 (patch)
tree432c668f79dd5a6e2ab36a2d8245bbb9854ea290 /externals/grill
parent5900c016e598f4ecad34495e02995d05dfa1a4f3 (diff)
""
svn path=/trunk/; revision=433
Diffstat (limited to 'externals/grill')
-rw-r--r--externals/grill/dyn/config-pd-linux.txt2
-rw-r--r--externals/grill/dyn/src/main.cpp3
-rw-r--r--externals/grill/pool/data.cpp568
-rw-r--r--externals/grill/pool/pool.cpp1228
-rw-r--r--externals/grill/pool/pool.dsp230
-rw-r--r--externals/grill/vst/src/EditorThread.cpp120
-rw-r--r--externals/grill/vst/src/VstHost.cpp1082
-rwxr-xr-xexternals/grill/xsample/xsample.cwbin155147 -> 155147 bytes
8 files changed, 1617 insertions, 1616 deletions
diff --git a/externals/grill/dyn/config-pd-linux.txt b/externals/grill/dyn/config-pd-linux.txt
index 55159ebb..732d86c1 100644
--- a/externals/grill/dyn/config-pd-linux.txt
+++ b/externals/grill/dyn/config-pd-linux.txt
@@ -21,7 +21,7 @@ TARGDIR=./pd-linux
# where should the external be installed?
# (leave blank to omit installation)
-INSTPATH=/usr/local/lib/pd/extra
+#INSTPATH=/usr/local/lib/pd/extra
# additional compiler flags
diff --git a/externals/grill/dyn/src/main.cpp b/externals/grill/dyn/src/main.cpp
index 9226fc17..afec7057 100644
--- a/externals/grill/dyn/src/main.cpp
+++ b/externals/grill/dyn/src/main.cpp
@@ -308,7 +308,8 @@ void dyn::obj::Add(obj *o) { if(nxt) nxt->Add(o); else nxt = o; }
dyn::obj *dyn::Find(const t_symbol *n)
{
- for(obj *o = root; o && o->name != n; o = o->nxt) {}
+ obj *o;
+ for(o = root; o && o->name != n; o = o->nxt) {}
return o;
}
diff --git a/externals/grill/pool/data.cpp b/externals/grill/pool/data.cpp
index 8ea6cc57..02ee4132 100644
--- a/externals/grill/pool/data.cpp
+++ b/externals/grill/pool/data.cpp
@@ -1,284 +1,284 @@
-/*
-
-pool - 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.
-
-*/
-
-#include "pool.h"
-
-#include <string.h>
-#include <fstream.h>
-#include <ctype.h>
-#include <stdlib.h>
-
-
-pooldata::pooldata(const S *s,I vcnt,I dcnt):
- sym(s),nxt(NULL),refs(0),
- root(nullatom,NULL,vcnt,dcnt)
-{
- LOG1("new pool %s",sym?flext_base::GetString(sym):"<private>");
-}
-
-pooldata::~pooldata()
-{
- LOG1("free pool %s",sym?flext_base::GetString(sym):"<private>");
-}
-
-
-const A pooldata::nullatom = { A_NULL };
-
-
-V pooldata::Reset()
-{
- root.Reset();
-}
-
-BL pooldata::MkDir(const AtomList &d,I vcnt,I dcnt)
-{
- root.AddDir(d,vcnt,dcnt);
- return true;
-}
-
-BL pooldata::ChkDir(const AtomList &d)
-{
- return root.GetDir(d) != NULL;
-}
-
-BL pooldata::RmDir(const AtomList &d)
-{
- return root.DelDir(d);
-}
-
-BL pooldata::Set(const AtomList &d,const A &key,AtomList *data,BL over)
-{
- pooldir *pd = root.GetDir(d);
- if(!pd) return false;
- pd->SetVal(key,data,over);
- return true;
-}
-
-BL pooldata::Clr(const AtomList &d,const A &key)
-{
- pooldir *pd = root.GetDir(d);
- if(!pd) return false;
- pd->ClrVal(key);
- return true;
-}
-
-BL pooldata::ClrAll(const AtomList &d,BL rec,BL dironly)
-{
- pooldir *pd = root.GetDir(d);
- if(!pd) return false;
- pd->Clear(rec,dironly);
- return true;
-}
-
-flext::AtomList *pooldata::Peek(const AtomList &d,const A &key)
-{
- pooldir *pd = root.GetDir(d);
- return pd?pd->PeekVal(key):NULL;
-}
-
-poolval *pooldata::Ref(const AtomList &d,const A &key)
-{
- pooldir *pd = root.GetDir(d);
- return pd?pd->RefVal(key):NULL;
-}
-
-poolval *pooldata::Refi(const AtomList &d,I ix)
-{
- pooldir *pd = root.GetDir(d);
- return pd?pd->RefVali(ix):NULL;
-}
-
-flext::AtomList *pooldata::Get(const AtomList &d,const A &key)
-{
- pooldir *pd = root.GetDir(d);
- return pd?pd->GetVal(key):NULL;
-}
-
-I pooldata::CntAll(const AtomList &d)
-{
- pooldir *pd = root.GetDir(d);
- return pd?pd->CntAll():0;
-}
-
-I pooldata::GetAll(const AtomList &d,A *&keys,AtomList *&lst)
-{
- pooldir *pd = root.GetDir(d);
- if(pd)
- return pd->GetAll(keys,lst);
- else {
- keys = NULL; lst = NULL;
- return 0;
- }
-}
-
-I pooldata::CntSub(const AtomList &d)
-{
- pooldir *pd = root.GetDir(d);
- return pd?pd->CntSub():0;
-}
-
-I pooldata::GetSub(const AtomList &d,const t_atom **&dirs)
-{
- pooldir *pd = root.GetDir(d);
- if(pd)
- return pd->GetSub(dirs);
- else {
- dirs = NULL;
- return 0;
- }
-}
-
-
-BL pooldata::Paste(const AtomList &d,const pooldir *clip,I depth,BL repl,BL mkdir)
-{
- pooldir *pd = root.GetDir(d);
- if(pd)
- return pd->Paste(clip,depth,repl,mkdir);
- else
- return false;
-}
-
-pooldir *pooldata::Copy(const AtomList &d,const A &key,BL cut)
-{
- pooldir *pd = root.GetDir(d);
- if(pd) {
- AtomList *val = pd->GetVal(key,cut);
- if(val) {
- pooldir *ret = new pooldir(nullatom,NULL,pd->VSize(),pd->DSize());
- ret->SetVal(key,val);
- return ret;
- }
- else
- return NULL;
- }
- else
- return NULL;
-}
-
-pooldir *pooldata::CopyAll(const AtomList &d,I depth,BL cut)
-{
- pooldir *pd = root.GetDir(d);
- if(pd) {
- // What sizes should we choose here?
- pooldir *ret = new pooldir(nullatom,NULL,pd->VSize(),pd->DSize());
- if(pd->Copy(ret,depth,cut))
- return ret;
- else {
- delete ret;
- return NULL;
- }
- }
- else
- return NULL;
-}
-
-
-static const C *CnvFlnm(C *dst,const C *src,I sz)
-{
-#if FLEXT_SYS == FLEXT_SYS_PD && FLEXT_OS == FLEXT_OS_WIN
- I i,cnt = strlen(src);
- if(cnt >= sz-1) return NULL;
- for(i = 0; i < cnt; ++i)
- dst[i] = src[i] != '/'?src[i]:'\\';
- dst[i] = 0;
- return dst;
-#else
- return src;
-#endif
-}
-
-BL pooldata::LdDir(const AtomList &d,const C *flnm,I depth,BL mkdir)
-{
- pooldir *pd = root.GetDir(d);
- if(pd) {
- C tmp[1024];
- const C *t = CnvFlnm(tmp,flnm,sizeof tmp);
- if(t) {
- ifstream fl(t);
- return fl.good() && pd->LdDir(fl,depth,mkdir);
- }
- else return false;
- }
- else
- return false;
-}
-
-BL pooldata::SvDir(const AtomList &d,const C *flnm,I depth,BL absdir)
-{
- pooldir *pd = root.GetDir(d);
- if(pd) {
- C tmp[1024];
- const C *t = CnvFlnm(tmp,flnm,sizeof tmp);
- if(t) {
- ofstream fl(t);
- AtomList tmp;
- if(absdir) tmp = d;
- return fl.good() && pd->SvDir(fl,depth,tmp);
- }
- else return false;
- }
- else
- return false;
-}
-
-BL pooldata::LdDirXML(const AtomList &d,const C *flnm,I depth,BL mkdir)
-{
- pooldir *pd = root.GetDir(d);
- if(pd) {
- C tmp[1024];
- const C *t = CnvFlnm(tmp,flnm,sizeof tmp);
- if(t) {
- ifstream fl(t);
- BL ret = fl.good() != 0;
- if(ret) {
- fl.getline(tmp,sizeof tmp);
- ret = !strncmp(tmp,"<?xml",5);
- }
- if(ret) {
- fl.getline(tmp,sizeof tmp);
- // DOCTYPE need not be present / only external DOCTYPE is allowed!
- if(!strncmp(tmp,"<!DOCTYPE",9))
- fl.getline(tmp,sizeof tmp);
- ret = !strncmp(tmp,"<pool>",6);
- }
- if(ret)
- ret = pd->LdDirXML(fl,depth,mkdir);
- return ret;
- }
- }
-
- return false;
-}
-
-BL pooldata::SvDirXML(const AtomList &d,const C *flnm,I depth,BL absdir)
-{
- pooldir *pd = root.GetDir(d);
- if(pd) {
- C tmp[1024];
- const C *t = CnvFlnm(tmp,flnm,sizeof tmp);
- if(t) {
- ofstream fl(t);
- AtomList tmp;
- if(absdir) tmp = d;
- if(fl.good()) {
- fl << "<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>" << endl;
- fl << "<!DOCTYPE pool SYSTEM \"pool.dtd\">" << endl;
- fl << "<pool>" << endl;
- BL ret = pd->SvDirXML(fl,depth,tmp);
- fl << "</pool>" << endl;
- return ret;
- }
- }
- }
-
- return false;
-}
-
-
+/*
+
+pool - 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.
+
+*/
+
+#include "pool.h"
+
+#include <string.h>
+#include <fstream.h>
+#include <ctype.h>
+#include <stdlib.h>
+
+
+pooldata::pooldata(const S *s,I vcnt,I dcnt):
+ sym(s),nxt(NULL),refs(0),
+ root(nullatom,NULL,vcnt,dcnt)
+{
+ FLEXT_LOG1("new pool %s",sym?flext_base::GetString(sym):"<private>");
+}
+
+pooldata::~pooldata()
+{
+ FLEXT_LOG1("free pool %s",sym?flext_base::GetString(sym):"<private>");
+}
+
+
+const A pooldata::nullatom = { A_NULL };
+
+
+V pooldata::Reset()
+{
+ root.Reset();
+}
+
+BL pooldata::MkDir(const AtomList &d,I vcnt,I dcnt)
+{
+ root.AddDir(d,vcnt,dcnt);
+ return true;
+}
+
+BL pooldata::ChkDir(const AtomList &d)
+{
+ return root.GetDir(d) != NULL;
+}
+
+BL pooldata::RmDir(const AtomList &d)
+{
+ return root.DelDir(d);
+}
+
+BL pooldata::Set(const AtomList &d,const A &key,AtomList *data,BL over)
+{
+ pooldir *pd = root.GetDir(d);
+ if(!pd) return false;
+ pd->SetVal(key,data,over);
+ return true;
+}
+
+BL pooldata::Clr(const AtomList &d,const A &key)
+{
+ pooldir *pd = root.GetDir(d);
+ if(!pd) return false;
+ pd->ClrVal(key);
+ return true;
+}
+
+BL pooldata::ClrAll(const AtomList &d,BL rec,BL dironly)
+{
+ pooldir *pd = root.GetDir(d);
+ if(!pd) return false;
+ pd->Clear(rec,dironly);
+ return true;
+}
+
+flext::AtomList *pooldata::Peek(const AtomList &d,const A &key)
+{
+ pooldir *pd = root.GetDir(d);
+ return pd?pd->PeekVal(key):NULL;
+}
+
+poolval *pooldata::Ref(const AtomList &d,const A &key)
+{
+ pooldir *pd = root.GetDir(d);
+ return pd?pd->RefVal(key):NULL;
+}
+
+poolval *pooldata::Refi(const AtomList &d,I ix)
+{
+ pooldir *pd = root.GetDir(d);
+ return pd?pd->RefVali(ix):NULL;
+}
+
+flext::AtomList *pooldata::Get(const AtomList &d,const A &key)
+{
+ pooldir *pd = root.GetDir(d);
+ return pd?pd->GetVal(key):NULL;
+}
+
+I pooldata::CntAll(const AtomList &d)
+{
+ pooldir *pd = root.GetDir(d);
+ return pd?pd->CntAll():0;
+}
+
+I pooldata::GetAll(const AtomList &d,A *&keys,AtomList *&lst)
+{
+ pooldir *pd = root.GetDir(d);
+ if(pd)
+ return pd->GetAll(keys,lst);
+ else {
+ keys = NULL; lst = NULL;
+ return 0;
+ }
+}
+
+I pooldata::CntSub(const AtomList &d)
+{
+ pooldir *pd = root.GetDir(d);
+ return pd?pd->CntSub():0;
+}
+
+I pooldata::GetSub(const AtomList &d,const t_atom **&dirs)
+{
+ pooldir *pd = root.GetDir(d);
+ if(pd)
+ return pd->GetSub(dirs);
+ else {
+ dirs = NULL;
+ return 0;
+ }
+}
+
+
+BL pooldata::Paste(const AtomList &d,const pooldir *clip,I depth,BL repl,BL mkdir)
+{
+ pooldir *pd = root.GetDir(d);
+ if(pd)
+ return pd->Paste(clip,depth,repl,mkdir);
+ else
+ return false;
+}
+
+pooldir *pooldata::Copy(const AtomList &d,const A &key,BL cut)
+{
+ pooldir *pd = root.GetDir(d);
+ if(pd) {
+ AtomList *val = pd->GetVal(key,cut);
+ if(val) {
+ pooldir *ret = new pooldir(nullatom,NULL,pd->VSize(),pd->DSize());
+ ret->SetVal(key,val);
+ return ret;
+ }
+ else
+ return NULL;
+ }
+ else
+ return NULL;
+}
+
+pooldir *pooldata::CopyAll(const AtomList &d,I depth,BL cut)
+{
+ pooldir *pd = root.GetDir(d);
+ if(pd) {
+ // What sizes should we choose here?
+ pooldir *ret = new pooldir(nullatom,NULL,pd->VSize(),pd->DSize());
+ if(pd->Copy(ret,depth,cut))
+ return ret;
+ else {
+ delete ret;
+ return NULL;
+ }
+ }
+ else
+ return NULL;
+}
+
+
+static const C *CnvFlnm(C *dst,const C *src,I sz)
+{
+#if FLEXT_SYS == FLEXT_SYS_PD && FLEXT_OS == FLEXT_OS_WIN
+ I i,cnt = strlen(src);
+ if(cnt >= sz-1) return NULL;
+ for(i = 0; i < cnt; ++i)
+ dst[i] = src[i] != '/'?src[i]:'\\';
+ dst[i] = 0;
+ return dst;
+#else
+ return src;
+#endif
+}
+
+BL pooldata::LdDir(const AtomList &d,const C *flnm,I depth,BL mkdir)
+{
+ pooldir *pd = root.GetDir(d);
+ if(pd) {
+ C tmp[1024];
+ const C *t = CnvFlnm(tmp,flnm,sizeof tmp);
+ if(t) {
+ ifstream fl(t);
+ return fl.good() && pd->LdDir(fl,depth,mkdir);
+ }
+ else return false;
+ }
+ else
+ return false;
+}
+
+BL pooldata::SvDir(const AtomList &d,const C *flnm,I depth,BL absdir)
+{
+ pooldir *pd = root.GetDir(d);
+ if(pd) {
+ C tmp[1024];
+ const C *t = CnvFlnm(tmp,flnm,sizeof tmp);
+ if(t) {
+ ofstream fl(t);
+ AtomList tmp;
+ if(absdir) tmp = d;
+ return fl.good() && pd->SvDir(fl,depth,tmp);
+ }
+ else return false;
+ }
+ else
+ return false;
+}
+
+BL pooldata::LdDirXML(const AtomList &d,const C *flnm,I depth,BL mkdir)
+{
+ pooldir *pd = root.GetDir(d);
+ if(pd) {
+ C tmp[1024];
+ const C *t = CnvFlnm(tmp,flnm,sizeof tmp);
+ if(t) {
+ ifstream fl(t);
+ BL ret = fl.good() != 0;
+ if(ret) {
+ fl.getline(tmp,sizeof tmp);
+ ret = !strncmp(tmp,"<?xml",5);
+ }
+ if(ret) {
+ fl.getline(tmp,sizeof tmp);
+ // DOCTYPE need not be present / only external DOCTYPE is allowed!
+ if(!strncmp(tmp,"<!DOCTYPE",9))
+ fl.getline(tmp,sizeof tmp);
+ ret = !strncmp(tmp,"<pool>",6);
+ }
+ if(ret)
+ ret = pd->LdDirXML(fl,depth,mkdir);
+ return ret;
+ }
+ }
+
+ return false;
+}
+
+BL pooldata::SvDirXML(const AtomList &d,const C *flnm,I depth,BL absdir)
+{
+ pooldir *pd = root.GetDir(d);
+ if(pd) {
+ C tmp[1024];
+ const C *t = CnvFlnm(tmp,flnm,sizeof tmp);
+ if(t) {
+ ofstream fl(t);
+ AtomList tmp;
+ if(absdir) tmp = d;
+ if(fl.good()) {
+ fl << "<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>" << endl;
+ fl << "<!DOCTYPE pool SYSTEM \"pool.dtd\">" << endl;
+ fl << "<pool>" << endl;
+ BL ret = pd->SvDirXML(fl,depth,tmp);
+ fl << "</pool>" << endl;
+ return ret;
+ }
+ }
+ }
+
+ return false;
+}
+
+
diff --git a/externals/grill/pool/pool.cpp b/externals/grill/pool/pool.cpp
index 5eb48294..68c9a266 100644
--- a/externals/grill/pool/pool.cpp
+++ b/externals/grill/pool/pool.cpp
@@ -1,614 +1,614 @@
-/*
-
-pool - 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.
-
-*/
-
-#include "pool.h"
-
-#include <string.h>
-#include <fstream.h>
-#include <ctype.h>
-#include <stdlib.h>
-
-#define VBITS 6
-#define DBITS 5
-
-inline I compare(I a,I b) { return a == b?0:(a < b?-1:1); }
-inline I compare(F a,F b) { return a == b?0:(a < b?-1:1); }
-
-static I compare(const S *a,const S *b)
-{
- if(a == b)
- return 0;
- else
- return strcmp(flext::GetString(a),flext::GetString(b));
-}
-
-static I compare(const A &a,const A &b)
-{
- if(flext::GetType(a) == flext::GetType(b)) {
- switch(flext::GetType(a)) {
- case A_FLOAT:
- return compare(flext::GetFloat(a),flext::GetFloat(b));
-#if FLEXT_SYS == FLEXT_SYS_MAX
- case A_LONG:
- return compare(flext::GetInt(a),flext::GetInt(b));
-#endif
- case A_SYMBOL:
- return compare(flext::GetSymbol(a),flext::GetSymbol(b));
-#if FLEXT_SYS == FLEXT_SYS_PD
- case A_POINTER:
- return flext::GetPointer(a) == flext::GetPointer(b)?0:(flext::GetPointer(a) < flext::GetPointer(b)?-1:1);
-#endif
- default:
- LOG("pool - atom comparison: type not handled");
- return -1;
- }
- }
- else
- return flext::GetType(a) < flext::GetType(b)?-1:1;
-}
-
-
-poolval::poolval(const A &k,AtomList *d):
- data(d),nxt(NULL)
-{
- SetAtom(key,k);
-}
-
-poolval::~poolval()
-{
- if(data) delete data;
- if(nxt) delete nxt;
-}
-
-poolval &poolval::Set(AtomList *d)
-{
- if(data) delete data;
- data = d;
- return *this;
-}
-
-poolval *poolval::Dup() const
-{
- return new poolval(key,data?new AtomList(*data):NULL);
-}
-
-
-pooldir::pooldir(const A &d,pooldir *p,I vcnt,I dcnt):
- parent(p),nxt(NULL),vals(NULL),dirs(NULL),
- vbits(vcnt?Int2Bits(vcnt):VBITS),dbits(dcnt?Int2Bits(dcnt):DBITS),
- vsize(1<<vbits),dsize(1<<dbits)
-{
- Reset();
- CopyAtom(&dir,&d);
-}
-
-pooldir::~pooldir()
-{
- Reset(false);
-
- if(nxt) delete nxt;
-}
-
-V pooldir::Clear(BL rec,BL dironly)
-{
- if(rec && dirs) {
- for(I i = 0; i < dsize; ++i) if(dirs[i].d) { delete dirs[i].d; dirs[i].d = NULL; }
- }
- if(!dironly && vals) {
- for(I i = 0; i < vsize; ++i) if(vals[i].v) { delete vals[i].v; vals[i].v = NULL; }
- }
-}
-
-V pooldir::Reset(BL realloc)
-{
- Clear(true,false);
-
- if(dirs) delete[] dirs;
- if(vals) delete[] vals;
-
- if(realloc) {
- dirs = new direntry[dsize];
- ZeroMem(dirs,dsize*sizeof *dirs);
- vals = new valentry[vsize];
- ZeroMem(vals,vsize*sizeof *vals);
- }
- else
- dirs = NULL,vals = NULL;
-}
-
-pooldir *pooldir::AddDir(I argc,const A *argv,I vcnt,I dcnt)
-{
- if(!argc) return this;
-
- I c = 1,dix = DIdx(argv[0]);
- pooldir *prv = NULL,*ix = dirs[dix].d;
- for(; ix; prv = ix,ix = ix->nxt) {
- c = compare(argv[0],ix->dir);
- if(c <= 0) break;
- }
-
- if(c || !ix) {
- pooldir *nd = new pooldir(argv[0],this,vcnt,dcnt);
- nd->nxt = ix;
-
- if(prv) prv->nxt = nd;
- else dirs[dix].d = nd;
- dirs[dix].cnt++;
- ix = nd;
- }
-
- return ix->AddDir(argc-1,argv+1);
-}
-
-pooldir *pooldir::GetDir(I argc,const A *argv,BL rmv)
-{
- if(!argc) return this;
-
- I c = 1,dix = DIdx(argv[0]);
- pooldir *prv = NULL,*ix = dirs[dix].d;
- for(; ix; prv = ix,ix = ix->nxt) {
- c = compare(argv[0],ix->dir);
- if(c <= 0) break;
- }
-
- if(c || !ix)
- return NULL;
- else {
- if(argc > 1)
- return ix->GetDir(argc-1,argv+1,rmv);
- else if(rmv) {
- pooldir *nd = ix->nxt;
- if(prv) prv->nxt = nd;
- else dirs[dix].d = nd;
- dirs[dix].cnt--;
- ix->nxt = NULL;
- return ix;
- }
- else
- return ix;
- }
-}
-
-BL pooldir::DelDir(I argc,const A *argv)
-{
- pooldir *pd = GetDir(argc,argv,true);
- if(pd && pd != this) {
- delete pd;
- return true;
- }
- else
- return false;
-}
-
-V pooldir::SetVal(const A &key,AtomList *data,BL over)
-{
- I c = 1,vix = VIdx(key);
- poolval *prv = NULL,*ix = vals[vix].v;
- for(; ix; prv = ix,ix = ix->nxt) {
- c = compare(key,ix->key);
- if(c <= 0) break;
- }
-
- if(c || !ix) {
- // no existing data found
-
- if(data) {
- poolval *nv = new poolval(key,data);
- nv->nxt = ix;
-
- if(prv) prv->nxt = nv;
- else vals[vix].v = nv;
- vals[vix].cnt++;
- }
- }
- else if(over) {
- // data exists... only set if overwriting enabled
-
- if(data)
- ix->Set(data);
- else {
- // delete key
-
- poolval *nv = ix->nxt;
- if(prv) prv->nxt = nv;
- else vals[vix].v = nv;
- vals[vix].cnt--;
- ix->nxt = NULL;
- delete ix;
- }
- }
-}
-
-poolval *pooldir::RefVal(const A &key)
-{
- I c = 1,vix = VIdx(key);
- poolval *ix = vals[vix].v;
- for(; ix; ix = ix->nxt) {
- c = compare(key,ix->key);
- if(c <= 0) break;
- }
-
- return c || !ix?NULL:ix;
-}
-
-
-poolval *pooldir::RefVali(I rix)
-{
- for(I vix = 0; vix < vsize; ++vix)
- if(rix > vals[vix].cnt) rix -= vals[vix].cnt;
- else {
- poolval *ix = vals[vix].v;
- for(; ix && rix; ix = ix->nxt) --rix;
- if(ix && !rix) return ix;
- }
- return NULL;
-}
-
-flext::AtomList *pooldir::PeekVal(const A &key)
-{
- poolval *ix = RefVal(key);
- return ix?ix->data:NULL;
-}
-
-flext::AtomList *pooldir::GetVal(const A &key,BL cut)
-{
- I c = 1,vix = VIdx(key);
- poolval *prv = NULL,*ix = vals[vix].v;
- for(; ix; prv = ix,ix = ix->nxt) {
- c = compare(key,ix->key);
- if(c <= 0) break;
- }
-
- if(c || !ix)
- return NULL;
- else {
- AtomList *ret;
- if(cut) {
- poolval *nv = ix->nxt;
- if(prv) prv->nxt = nv;
- else vals[vix].v = nv;
- vals[vix].cnt--;
- ix->nxt = NULL;
- ret = ix->data; ix->data = NULL;
- delete ix;
- }
- else
- ret = new AtomList(*ix->data);
- return ret;
- }
-}
-
-I pooldir::CntAll() const
-{
- I cnt = 0;
- for(I vix = 0; vix < vsize; ++vix) cnt += vals[vix].cnt;
- return cnt;
-}
-
-I pooldir::GetKeys(AtomList &keys)
-{
- I cnt = CntAll();
- keys(cnt);
-
- for(I vix = 0; vix < vsize; ++vix) {
- poolval *ix = vals[vix].v;
- for(I i = 0; ix; ++i,ix = ix->nxt)
- SetAtom(keys[i],ix->key);
- }
- return cnt;
-}
-
-I pooldir::GetAll(A *&keys,AtomList *&lst,BL cut)
-{
- I cnt = CntAll();
- keys = new A[cnt];
- lst = new AtomList[cnt];
-
- for(I i = 0,vix = 0; vix < vsize; ++vix) {
- poolval *ix = vals[vix].v;
- for(; ix; ++i) {
- SetAtom(keys[i],ix->key);
- lst[i] = *ix->data;
-
- if(cut) {
- poolval *t = ix;
- vals[vix].v = ix = ix->nxt;
- vals[vix].cnt--;
- t->nxt = NULL; delete t;
- }
- else
- ix = ix->nxt;
- }
- }
- return cnt;
-}
-
-
-I pooldir::CntSub() const
-{
- I cnt = 0;
- for(I dix = 0; dix < dsize; ++dix) cnt += dirs[dix].cnt;
- return cnt;
-}
-
-
-I pooldir::GetSub(const A **&lst)
-{
- const I cnt = CntSub();
- lst = new const A *[cnt];
- for(I i = 0,dix = 0; dix < dsize; ++dix) {
- pooldir *ix = dirs[dix].d;
- for(; ix; ix = ix->nxt) lst[i++] = &ix->dir;
- }
- return cnt;
-}
-
-
-BL pooldir::Paste(const pooldir *p,I depth,BL repl,BL mkdir)
-{
- BL ok = true;
-
- for(I vi = 0; vi < p->vsize; ++vi) {
- for(poolval *ix = p->vals[vi].v; ix; ix = ix->nxt) {
- SetVal(ix->key,new AtomList(*ix->data),repl);
- }
- }
-
- if(ok && depth) {
- for(I di = 0; di < p->dsize; ++di) {
- for(pooldir *dix = p->dirs[di].d; ok && dix; dix = dix->nxt) {
- pooldir *ndir = mkdir?AddDir(1,&dix->dir):GetDir(1,&dix->dir);
- if(ndir) {
- ok = ndir->Paste(dix,depth > 0?depth-1:depth,repl,mkdir);
- }
- }
- }
- }
-
- return ok;
-}
-
-BL pooldir::Copy(pooldir *p,I depth,BL cut)
-{
- BL ok = true;
-
- if(cut) {
- for(I vi = 0; vi < vsize; ++vi) {
- for(poolval *ix = vals[vi].v; ix; ix = ix->nxt)
- p->SetVal(ix->key,ix->data);
- vals[vi].cnt = 0;
- vals[vi].v = NULL;
- }
- }
- else {
- for(I vi = 0; vi < vsize; ++vi) {
- for(poolval *ix = vals[vi].v; ix; ix = ix->nxt) {
- p->SetVal(ix->key,new AtomList(*ix->data));
- }
- }
- }
-
- if(ok && depth) {
- for(I di = 0; di < dsize; ++di) {
- for(pooldir *dix = dirs[di].d; ok && dix; dix = dix->nxt) {
- pooldir *ndir = p->AddDir(1,&dix->dir);
- if(ndir)
- ok = ndir->Copy(dix,depth > 0?depth-1:depth,cut);
- else
- ok = false;
- }
- }
- }
-
- return ok;
-}
-
-
-static C *ReadAtom(C *c,A *a)
-{
- // skip whitespace
- while(*c && isspace(*c)) ++c;
- if(!*c) return NULL;
-
- const C *m = c; // remember position
-
- // check for word type (s = 0,1,2 ... int,float,symbol)
- I s = 0;
- for(; *c && !isspace(*c); ++c) {
- if(!isdigit(*c))
- s = (*c != '.' || s == 1)?2:1;
- }
-
- if(a) {
- switch(s) {
- case 0: // integer
-#if FLEXT_SYS == FLEXT_SYS_MAX
- flext::SetInt(*a,atoi(m));
- break;
-#endif
- case 1: // float
- flext::SetFloat(*a,(F)atof(m));
- break;
- default: { // anything else is a symbol
- C t = *c; *c = 0;
- flext::SetString(*a,m);
- *c = t;
- break;
- }
- }
- }
-
- return c;
-}
-
-static BL ReadAtoms(istream &is,flext::AtomList &l,C del)
-{
- C tmp[1024];
- is.getline(tmp,sizeof tmp,del);
- if(is.eof() || !is.good()) return false;
-
- I i,cnt;
- C *t = tmp;
- for(cnt = 0; ; ++cnt) {
- t = ReadAtom(t,NULL);
- if(!t) break;
- }
-
- l(cnt);
- if(cnt) {
- for(i = 0,t = tmp; i < cnt; ++i)
- t = ReadAtom(t,&l[i]);
- }
- return true;
-}
-
-static V WriteAtom(ostream &os,const A &a)
-{
- switch(a.a_type) {
- case A_FLOAT:
- os << a.a_w.w_float;
- break;
-#if FLEXT_SYS == FLEXT_SYS_MAX
- case A_LONG:
- os << a.a_w.w_long;
- break;
-#endif
- case A_SYMBOL:
- os << flext::GetString(flext::GetSymbol(a));
- break;
- }
-}
-
-static V WriteAtoms(ostream &os,const flext::AtomList &l)
-{
- for(I i = 0; i < l.Count(); ++i) {
-// if(IsSymbol(l[i]) os << "\"";
- WriteAtom(os,l[i]);
-// if(IsSymbol(l[i]) os << "\"";
- if(i < l.Count()-1) os << ' ';
- }
-}
-
-BL pooldir::LdDir(istream &is,I depth,BL mkdir)
-{
- for(I i = 1; !is.eof(); ++i) {
- AtomList d,k,*v = new AtomList;
- BL r = ReadAtoms(is,d,',');
- r = r && ReadAtoms(is,k,',') && k.Count() == 1;
- r = r && ReadAtoms(is,*v,'\n') && v->Count();
-
- if(r) {
- if(depth < 0 || d.Count() <= depth) {
- pooldir *nd = mkdir?AddDir(d):GetDir(d);
- if(nd) {
- nd->SetVal(k[0],v); v = NULL;
- }
- #ifdef FLEXT_DEBUG
- else
- post("pool - directory was not found",i);
- #endif
- }
- }
- else if(!is.eof())
- post("pool - format mismatch encountered, skipped line %i",i);
-
- if(v) delete v;
- }
- return true;
-}
-
-BL pooldir::SvDir(ostream &os,I depth,const AtomList &dir)
-{
- for(I vi = 0; vi < vsize; ++vi) {
- for(poolval *ix = vals[vi].v; ix; ix = ix->nxt) {
- WriteAtoms(os,dir);
- os << " , ";
- WriteAtom(os,ix->key);
- os << " , ";
- WriteAtoms(os,*ix->data);
- os << endl;
- }
- }
- if(depth) {
- I nd = depth > 0?depth-1:-1;
- for(I di = 0; di < dsize; ++di) {
- for(pooldir *ix = dirs[di].d; ix; ix = ix->nxt) {
- ix->SvDir(os,nd,AtomList(dir).Append(ix->dir));
- }
- }
- }
- return true;
-}
-
-BL pooldir::LdDirXML(istream &is,I depth,BL mkdir)
-{
-/*
- for(I i = 1; !is.eof(); ++i) {
- AtomList d,k,*v = new AtomList;
- BL r = ReadAtoms(is,d,',');
- r = r && ReadAtoms(is,k,',') && k.Count() == 1;
- r = r && ReadAtoms(is,*v,'\n') && v->Count();
-
- if(r) {
- if(depth < 0 || d.Count() <= depth) {
- pooldir *nd = mkdir?AddDir(d):GetDir(d);
- if(nd) {
- nd->SetVal(k[0],v); v = NULL;
- }
- #ifdef FLEXT_DEBUG
- else
- post("pool - directory was not found",i);
- #endif
- }
- }
- else if(!is.eof())
- post("pool - format mismatch encountered, skipped line %i",i);
-
- if(v) delete v;
- }
- return true;
-*/
- return false;
-}
-
-BL pooldir::SvDirXML(ostream &os,I depth,const AtomList &dir)
-{
- if(dir.Count()) {
- os << "<dir key=\"";
- WriteAtom(os,dir[dir.Count()-1]);
- os << "\">" << endl;
- }
-
- for(I vi = 0; vi < vsize; ++vi) {
- for(poolval *ix = vals[vi].v; ix; ix = ix->nxt) {
- os << "<value key=\"";
- WriteAtom(os,ix->key);
- os << "\">";
- WriteAtoms(os,*ix->data);
- os << "</value>" << endl;
- }
- }
-
- if(depth) {
- I nd = depth > 0?depth-1:-1;
- for(I di = 0; di < dsize; ++di) {
- for(pooldir *ix = dirs[di].d; ix; ix = ix->nxt) {
- ix->SvDirXML(os,nd,AtomList(dir).Append(ix->dir));
- }
- }
- }
-
- if(dir.Count()) os << "</dir>" << endl;
- return true;
-}
-
-
-
-
+/*
+
+pool - 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.
+
+*/
+
+#include "pool.h"
+
+#include <string.h>
+#include <fstream.h>
+#include <ctype.h>
+#include <stdlib.h>
+
+#define VBITS 6
+#define DBITS 5
+
+inline I compare(I a,I b) { return a == b?0:(a < b?-1:1); }
+inline I compare(F a,F b) { return a == b?0:(a < b?-1:1); }
+
+static I compare(const S *a,const S *b)
+{
+ if(a == b)
+ return 0;
+ else
+ return strcmp(flext::GetString(a),flext::GetString(b));
+}
+
+static I compare(const A &a,const A &b)
+{
+ if(flext::GetType(a) == flext::GetType(b)) {
+ switch(flext::GetType(a)) {
+ case A_FLOAT:
+ return compare(flext::GetFloat(a),flext::GetFloat(b));
+#if FLEXT_SYS == FLEXT_SYS_MAX
+ case A_LONG:
+ return compare(flext::GetInt(a),flext::GetInt(b));
+#endif
+ case A_SYMBOL:
+ return compare(flext::GetSymbol(a),flext::GetSymbol(b));
+#if FLEXT_SYS == FLEXT_SYS_PD
+ case A_POINTER:
+ return flext::GetPointer(a) == flext::GetPointer(b)?0:(flext::GetPointer(a) < flext::GetPointer(b)?-1:1);
+#endif
+ default:
+ FLEXT_LOG("pool - atom comparison: type not handled");
+ return -1;
+ }
+ }
+ else
+ return flext::GetType(a) < flext::GetType(b)?-1:1;
+}
+
+
+poolval::poolval(const A &k,AtomList *d):
+ data(d),nxt(NULL)
+{
+ SetAtom(key,k);
+}
+
+poolval::~poolval()
+{
+ if(data) delete data;
+ if(nxt) delete nxt;
+}
+
+poolval &poolval::Set(AtomList *d)
+{
+ if(data) delete data;
+ data = d;
+ return *this;
+}
+
+poolval *poolval::Dup() const
+{
+ return new poolval(key,data?new AtomList(*data):NULL);
+}
+
+
+pooldir::pooldir(const A &d,pooldir *p,I vcnt,I dcnt):
+ parent(p),nxt(NULL),vals(NULL),dirs(NULL),
+ vbits(vcnt?Int2Bits(vcnt):VBITS),dbits(dcnt?Int2Bits(dcnt):DBITS),
+ vsize(1<<vbits),dsize(1<<dbits)
+{
+ Reset();
+ CopyAtom(&dir,&d);
+}
+
+pooldir::~pooldir()
+{
+ Reset(false);
+
+ if(nxt) delete nxt;
+}
+
+V pooldir::Clear(BL rec,BL dironly)
+{
+ if(rec && dirs) {
+ for(I i = 0; i < dsize; ++i) if(dirs[i].d) { delete dirs[i].d; dirs[i].d = NULL; }
+ }
+ if(!dironly && vals) {
+ for(I i = 0; i < vsize; ++i) if(vals[i].v) { delete vals[i].v; vals[i].v = NULL; }
+ }
+}
+
+V pooldir::Reset(BL realloc)
+{
+ Clear(true,false);
+
+ if(dirs) delete[] dirs;
+ if(vals) delete[] vals;
+
+ if(realloc) {
+ dirs = new direntry[dsize];
+ ZeroMem(dirs,dsize*sizeof *dirs);
+ vals = new valentry[vsize];
+ ZeroMem(vals,vsize*sizeof *vals);
+ }
+ else
+ dirs = NULL,vals = NULL;
+}
+
+pooldir *pooldir::AddDir(I argc,const A *argv,I vcnt,I dcnt)
+{
+ if(!argc) return this;
+
+ I c = 1,dix = DIdx(argv[0]);
+ pooldir *prv = NULL,*ix = dirs[dix].d;
+ for(; ix; prv = ix,ix = ix->nxt) {
+ c = compare(argv[0],ix->dir);
+ if(c <= 0) break;
+ }
+
+ if(c || !ix) {
+ pooldir *nd = new pooldir(argv[0],this,vcnt,dcnt);
+ nd->nxt = ix;
+
+ if(prv) prv->nxt = nd;
+ else dirs[dix].d = nd;
+ dirs[dix].cnt++;
+ ix = nd;
+ }
+
+ return ix->AddDir(argc-1,argv+1);
+}
+
+pooldir *pooldir::GetDir(I argc,const A *argv,BL rmv)
+{
+ if(!argc) return this;
+
+ I c = 1,dix = DIdx(argv[0]);
+ pooldir *prv = NULL,*ix = dirs[dix].d;
+ for(; ix; prv = ix,ix = ix->nxt) {
+ c = compare(argv[0],ix->dir);
+ if(c <= 0) break;
+ }
+
+ if(c || !ix)
+ return NULL;
+ else {
+ if(argc > 1)
+ return ix->GetDir(argc-1,argv+1,rmv);
+ else if(rmv) {
+ pooldir *nd = ix->nxt;
+ if(prv) prv->nxt = nd;
+ else dirs[dix].d = nd;
+ dirs[dix].cnt--;
+ ix->nxt = NULL;
+ return ix;
+ }
+ else
+ return ix;
+ }
+}
+
+BL pooldir::DelDir(I argc,const A *argv)
+{
+ pooldir *pd = GetDir(argc,argv,true);
+ if(pd && pd != this) {
+ delete pd;
+ return true;
+ }
+ else
+ return false;
+}
+
+V pooldir::SetVal(const A &key,AtomList *data,BL over)
+{
+ I c = 1,vix = VIdx(key);
+ poolval *prv = NULL,*ix = vals[vix].v;
+ for(; ix; prv = ix,ix = ix->nxt) {
+ c = compare(key,ix->key);
+ if(c <= 0) break;
+ }
+
+ if(c || !ix) {
+ // no existing data found
+
+ if(data) {
+ poolval *nv = new poolval(key,data);
+ nv->nxt = ix;
+
+ if(prv) prv->nxt = nv;
+ else vals[vix].v = nv;
+ vals[vix].cnt++;
+ }
+ }
+ else if(over) {
+ // data exists... only set if overwriting enabled
+
+ if(data)
+ ix->Set(data);
+ else {
+ // delete key
+
+ poolval *nv = ix->nxt;
+ if(prv) prv->nxt = nv;
+ else vals[vix].v = nv;
+ vals[vix].cnt--;
+ ix->nxt = NULL;
+ delete ix;
+ }
+ }
+}
+
+poolval *pooldir::RefVal(const A &key)
+{
+ I c = 1,vix = VIdx(key);
+ poolval *ix = vals[vix].v;
+ for(; ix; ix = ix->nxt) {
+ c = compare(key,ix->key);
+ if(c <= 0) break;
+ }
+
+ return c || !ix?NULL:ix;
+}
+
+
+poolval *pooldir::RefVali(I rix)
+{
+ for(I vix = 0; vix < vsize; ++vix)
+ if(rix > vals[vix].cnt) rix -= vals[vix].cnt;
+ else {
+ poolval *ix = vals[vix].v;
+ for(; ix && rix; ix = ix->nxt) --rix;
+ if(ix && !rix) return ix;
+ }
+ return NULL;
+}
+
+flext::AtomList *pooldir::PeekVal(const A &key)
+{
+ poolval *ix = RefVal(key);
+ return ix?ix->data:NULL;
+}
+
+flext::AtomList *pooldir::GetVal(const A &key,BL cut)
+{
+ I c = 1,vix = VIdx(key);
+ poolval *prv = NULL,*ix = vals[vix].v;
+ for(; ix; prv = ix,ix = ix->nxt) {
+ c = compare(key,ix->key);
+ if(c <= 0) break;
+ }
+
+ if(c || !ix)
+ return NULL;
+ else {
+ AtomList *ret;
+ if(cut) {
+ poolval *nv = ix->nxt;
+ if(prv) prv->nxt = nv;
+ else vals[vix].v = nv;
+ vals[vix].cnt--;
+ ix->nxt = NULL;
+ ret = ix->data; ix->data = NULL;
+ delete ix;
+ }
+ else
+ ret = new AtomList(*ix->data);
+ return ret;
+ }
+}
+
+I pooldir::CntAll() const
+{
+ I cnt = 0;
+ for(I vix = 0; vix < vsize; ++vix) cnt += vals[vix].cnt;
+ return cnt;
+}
+
+I pooldir::GetKeys(AtomList &keys)
+{
+ I cnt = CntAll();
+ keys(cnt);
+
+ for(I vix = 0; vix < vsize; ++vix) {
+ poolval *ix = vals[vix].v;
+ for(I i = 0; ix; ++i,ix = ix->nxt)
+ SetAtom(keys[i],ix->key);
+ }
+ return cnt;
+}
+
+I pooldir::GetAll(A *&keys,AtomList *&lst,BL cut)
+{
+ I cnt = CntAll();
+ keys = new A[cnt];
+ lst = new AtomList[cnt];
+
+ for(I i = 0,vix = 0; vix < vsize; ++vix) {
+ poolval *ix = vals[vix].v;
+ for(; ix; ++i) {
+ SetAtom(keys[i],ix->key);
+ lst[i] = *ix->data;
+
+ if(cut) {
+ poolval *t = ix;
+ vals[vix].v = ix = ix->nxt;
+ vals[vix].cnt--;
+ t->nxt = NULL; delete t;
+ }
+ else
+ ix = ix->nxt;
+ }
+ }
+ return cnt;
+}
+
+
+I pooldir::CntSub() const
+{
+ I cnt = 0;
+ for(I dix = 0; dix < dsize; ++dix) cnt += dirs[dix].cnt;
+ return cnt;
+}
+
+
+I pooldir::GetSub(const A **&lst)
+{
+ const I cnt = CntSub();
+ lst = new const A *[cnt];
+ for(I i = 0,dix = 0; dix < dsize; ++dix) {
+ pooldir *ix = dirs[dix].d;
+ for(; ix; ix = ix->nxt) lst[i++] = &ix->dir;
+ }
+ return cnt;
+}
+
+
+BL pooldir::Paste(const pooldir *p,I depth,BL repl,BL mkdir)
+{
+ BL ok = true;
+
+ for(I vi = 0; vi < p->vsize; ++vi) {
+ for(poolval *ix = p->vals[vi].v; ix; ix = ix->nxt) {
+ SetVal(ix->key,new AtomList(*ix->data),repl);
+ }
+ }
+
+ if(ok && depth) {
+ for(I di = 0; di < p->dsize; ++di) {
+ for(pooldir *dix = p->dirs[di].d; ok && dix; dix = dix->nxt) {
+ pooldir *ndir = mkdir?AddDir(1,&dix->dir):GetDir(1,&dix->dir);
+ if(ndir) {
+ ok = ndir->Paste(dix,depth > 0?depth-1:depth,repl,mkdir);
+ }
+ }
+ }
+ }
+
+ return ok;
+}
+
+BL pooldir::Copy(pooldir *p,I depth,BL cut)
+{
+ BL ok = true;
+
+ if(cut) {
+ for(I vi = 0; vi < vsize; ++vi) {
+ for(poolval *ix = vals[vi].v; ix; ix = ix->nxt)
+ p->SetVal(ix->key,ix->data);
+ vals[vi].cnt = 0;
+ vals[vi].v = NULL;
+ }
+ }
+ else {
+ for(I vi = 0; vi < vsize; ++vi) {
+ for(poolval *ix = vals[vi].v; ix; ix = ix->nxt) {
+ p->SetVal(ix->key,new AtomList(*ix->data));
+ }
+ }
+ }
+
+ if(ok && depth) {
+ for(I di = 0; di < dsize; ++di) {
+ for(pooldir *dix = dirs[di].d; ok && dix; dix = dix->nxt) {
+ pooldir *ndir = p->AddDir(1,&dix->dir);
+ if(ndir)
+ ok = ndir->Copy(dix,depth > 0?depth-1:depth,cut);
+ else
+ ok = false;
+ }
+ }
+ }
+
+ return ok;
+}
+
+
+static C *ReadAtom(C *c,A *a)
+{
+ // skip whitespace
+ while(*c && isspace(*c)) ++c;
+ if(!*c) return NULL;
+
+ const C *m = c; // remember position
+
+ // check for word type (s = 0,1,2 ... int,float,symbol)
+ I s = 0;
+ for(; *c && !isspace(*c); ++c) {
+ if(!isdigit(*c))
+ s = (*c != '.' || s == 1)?2:1;
+ }
+
+ if(a) {
+ switch(s) {
+ case 0: // integer
+#if FLEXT_SYS == FLEXT_SYS_MAX
+ flext::SetInt(*a,atoi(m));
+ break;
+#endif
+ case 1: // float
+ flext::SetFloat(*a,(F)atof(m));
+ break;
+ default: { // anything else is a symbol
+ C t = *c; *c = 0;
+ flext::SetString(*a,m);
+ *c = t;
+ break;
+ }
+ }
+ }
+
+ return c;
+}
+
+static BL ReadAtoms(istream &is,flext::AtomList &l,C del)
+{
+ C tmp[1024];
+ is.getline(tmp,sizeof tmp,del);
+ if(is.eof() || !is.good()) return false;
+
+ I i,cnt;
+ C *t = tmp;
+ for(cnt = 0; ; ++cnt) {
+ t = ReadAtom(t,NULL);
+ if(!t) break;
+ }
+
+ l(cnt);
+ if(cnt) {
+ for(i = 0,t = tmp; i < cnt; ++i)
+ t = ReadAtom(t,&l[i]);
+ }
+ return true;
+}
+
+static V WriteAtom(ostream &os,const A &a)
+{
+ switch(a.a_type) {
+ case A_FLOAT:
+ os << a.a_w.w_float;
+ break;
+#if FLEXT_SYS == FLEXT_SYS_MAX
+ case A_LONG:
+ os << a.a_w.w_long;
+ break;
+#endif
+ case A_SYMBOL:
+ os << flext::GetString(flext::GetSymbol(a));
+ break;
+ }
+}
+
+static V WriteAtoms(ostream &os,const flext::AtomList &l)
+{
+ for(I i = 0; i < l.Count(); ++i) {
+// if(IsSymbol(l[i]) os << "\"";
+ WriteAtom(os,l[i]);
+// if(IsSymbol(l[i]) os << "\"";
+ if(i < l.Count()-1) os << ' ';
+ }
+}
+
+BL pooldir::LdDir(istream &is,I depth,BL mkdir)
+{
+ for(I i = 1; !is.eof(); ++i) {
+ AtomList d,k,*v = new AtomList;
+ BL r = ReadAtoms(is,d,',');
+ r = r && ReadAtoms(is,k,',') && k.Count() == 1;
+ r = r && ReadAtoms(is,*v,'\n') && v->Count();
+
+ if(r) {
+ if(depth < 0 || d.Count() <= depth) {
+ pooldir *nd = mkdir?AddDir(d):GetDir(d);
+ if(nd) {
+ nd->SetVal(k[0],v); v = NULL;
+ }
+ #ifdef FLEXT_DEBUG
+ else
+ post("pool - directory was not found",i);
+ #endif
+ }
+ }
+ else if(!is.eof())
+ post("pool - format mismatch encountered, skipped line %i",i);
+
+ if(v) delete v;
+ }
+ return true;
+}
+
+BL pooldir::SvDir(ostream &os,I depth,const AtomList &dir)
+{
+ for(I vi = 0; vi < vsize; ++vi) {
+ for(poolval *ix = vals[vi].v; ix; ix = ix->nxt) {
+ WriteAtoms(os,dir);
+ os << " , ";
+ WriteAtom(os,ix->key);
+ os << " , ";
+ WriteAtoms(os,*ix->data);
+ os << endl;
+ }
+ }
+ if(depth) {
+ I nd = depth > 0?depth-1:-1;
+ for(I di = 0; di < dsize; ++di) {
+ for(pooldir *ix = dirs[di].d; ix; ix = ix->nxt) {
+ ix->SvDir(os,nd,AtomList(dir).Append(ix->dir));
+ }
+ }
+ }
+ return true;
+}
+
+BL pooldir::LdDirXML(istream &is,I depth,BL mkdir)
+{
+/*
+ for(I i = 1; !is.eof(); ++i) {
+ AtomList d,k,*v = new AtomList;
+ BL r = ReadAtoms(is,d,',');
+ r = r && ReadAtoms(is,k,',') && k.Count() == 1;
+ r = r && ReadAtoms(is,*v,'\n') && v->Count();
+
+ if(r) {
+ if(depth < 0 || d.Count() <= depth) {
+ pooldir *nd = mkdir?AddDir(d):GetDir(d);
+ if(nd) {
+ nd->SetVal(k[0],v); v = NULL;
+ }
+ #ifdef FLEXT_DEBUG
+ else
+ post("pool - directory was not found",i);
+ #endif
+ }
+ }
+ else if(!is.eof())
+ post("pool - format mismatch encountered, skipped line %i",i);
+
+ if(v) delete v;
+ }
+ return true;
+*/
+ return false;
+}
+
+BL pooldir::SvDirXML(ostream &os,I depth,const AtomList &dir)
+{
+ if(dir.Count()) {
+ os << "<dir key=\"";
+ WriteAtom(os,dir[dir.Count()-1]);
+ os << "\">" << endl;
+ }
+
+ for(I vi = 0; vi < vsize; ++vi) {
+ for(poolval *ix = vals[vi].v; ix; ix = ix->nxt) {
+ os << "<value key=\"";
+ WriteAtom(os,ix->key);
+ os << "\">";
+ WriteAtoms(os,*ix->data);
+ os << "</value>" << endl;
+ }
+ }
+
+ if(depth) {
+ I nd = depth > 0?depth-1:-1;
+ for(I di = 0; di < dsize; ++di) {
+ for(pooldir *ix = dirs[di].d; ix; ix = ix->nxt) {
+ ix->SvDirXML(os,nd,AtomList(dir).Append(ix->dir));
+ }
+ }
+ }
+
+ if(dir.Count()) os << "</dir>" << endl;
+ return true;
+}
+
+
+
+
diff --git a/externals/grill/pool/pool.dsp b/externals/grill/pool/pool.dsp
index f59a4e15..73518801 100644
--- a/externals/grill/pool/pool.dsp
+++ b/externals/grill/pool/pool.dsp
@@ -1,115 +1,115 @@
-# Microsoft Developer Studio Project File - Name="pool" - Package Owner=<4>
-# Microsoft Developer Studio Generated Build File, Format Version 6.00
-# ** NICHT BEARBEITEN **
-
-# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102
-
-CFG=pool - Win32 Debug
-!MESSAGE Dies ist kein gültiges Makefile. Zum Erstellen dieses Projekts mit NMAKE
-!MESSAGE verwenden Sie den Befehl "Makefile exportieren" und führen Sie den Befehl
-!MESSAGE
-!MESSAGE NMAKE /f "pool.mak".
-!MESSAGE
-!MESSAGE Sie können beim Ausführen von NMAKE eine Konfiguration angeben
-!MESSAGE durch Definieren des Makros CFG in der Befehlszeile. Zum Beispiel:
-!MESSAGE
-!MESSAGE NMAKE /f "pool.mak" CFG="pool - Win32 Debug"
-!MESSAGE
-!MESSAGE Für die Konfiguration stehen zur Auswahl:
-!MESSAGE
-!MESSAGE "pool - Win32 Release" (basierend auf "Win32 (x86) Dynamic-Link Library")
-!MESSAGE "pool - Win32 Debug" (basierend auf "Win32 (x86) Dynamic-Link Library")
-!MESSAGE
-
-# Begin Project
-# PROP AllowPerConfigDependencies 0
-# PROP Scc_ProjName "max/pool"
-# PROP Scc_LocalPath "."
-CPP=cl.exe
-MTL=midl.exe
-RSC=rc.exe
-
-!IF "$(CFG)" == "pool - Win32 Release"
-
-# PROP BASE Use_MFC 0
-# PROP BASE Use_Debug_Libraries 0
-# PROP BASE Output_Dir "Release"
-# PROP BASE Intermediate_Dir "Release"
-# PROP BASE Target_Dir ""
-# PROP Use_MFC 0
-# PROP Use_Debug_Libraries 0
-# PROP Output_Dir "pd-msvc/r"
-# PROP Intermediate_Dir "pd-msvc/r"
-# 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 "POOL_EXPORTS" /YX /FD /c
-# ADD CPP /nologo /W3 /GX /O2 /I "c:\programme\audio\pd\src" /I "f:\prog\max\flext\source" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D FLEXT_SYS=2 /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"
-# ADD RSC /l 0xc07 /d "NDEBUG"
-BSC32=bscmake.exe
-# ADD BASE BSC32 /nologo
-# 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_sh/pd-msvc/t/flext.lib /nologo /dll /machine:I386 /out:"pd-msvc/pool.dll" /libpath:"c:\programme\audio\pd\bin" /libpath:"f:\prog\max\flext\pd-msvc"
-
-!ELSEIF "$(CFG)" == "pool - Win32 Debug"
-
-# PROP BASE Use_MFC 0
-# PROP BASE Use_Debug_Libraries 1
-# PROP BASE Output_Dir "Debug"
-# PROP BASE Intermediate_Dir "Debug"
-# PROP BASE Target_Dir ""
-# PROP Use_MFC 0
-# PROP Use_Debug_Libraries 1
-# PROP Output_Dir "pd-msvc/d"
-# PROP Intermediate_Dir "pd-msvc/d"
-# 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 "POOL_EXPORTS" /YX /FD /GZ /c
-# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /I "c:\programme\audio\pd\src" /I "f:\prog\max\flext\source" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D FLEXT_SYS=2 /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"
-# ADD RSC /l 0xc07 /d "_DEBUG"
-BSC32=bscmake.exe
-# ADD BASE BSC32 /nologo
-# 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"
-
-!ENDIF
-
-# Begin Target
-
-# Name "pool - Win32 Release"
-# Name "pool - Win32 Debug"
-# Begin Source File
-
-SOURCE=.\data.cpp
-# End Source File
-# Begin Source File
-
-SOURCE=.\main.cpp
-# End Source File
-# Begin Source File
-
-SOURCE=.\pool.cpp
-# End Source File
-# Begin Source File
-
-SOURCE=.\pool.dtd
-# End Source File
-# Begin Source File
-
-SOURCE=.\pool.h
-# End Source File
-# Begin Source File
-
-SOURCE=.\readme.txt
-# End Source File
-# End Target
-# End Project
+# Microsoft Developer Studio Project File - Name="pool" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** NICHT BEARBEITEN **
+
+# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102
+
+CFG=pool - Win32 Debug
+!MESSAGE Dies ist kein gültiges Makefile. Zum Erstellen dieses Projekts mit NMAKE
+!MESSAGE verwenden Sie den Befehl "Makefile exportieren" und führen Sie den Befehl
+!MESSAGE
+!MESSAGE NMAKE /f "pool.mak".
+!MESSAGE
+!MESSAGE Sie können beim Ausführen von NMAKE eine Konfiguration angeben
+!MESSAGE durch Definieren des Makros CFG in der Befehlszeile. Zum Beispiel:
+!MESSAGE
+!MESSAGE NMAKE /f "pool.mak" CFG="pool - Win32 Debug"
+!MESSAGE
+!MESSAGE Für die Konfiguration stehen zur Auswahl:
+!MESSAGE
+!MESSAGE "pool - Win32 Release" (basierend auf "Win32 (x86) Dynamic-Link Library")
+!MESSAGE "pool - Win32 Debug" (basierend auf "Win32 (x86) Dynamic-Link Library")
+!MESSAGE
+
+# Begin Project
+# PROP AllowPerConfigDependencies 0
+# PROP Scc_ProjName "max/pool"
+# PROP Scc_LocalPath "."
+CPP=cl.exe
+MTL=midl.exe
+RSC=rc.exe
+
+!IF "$(CFG)" == "pool - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "pd-msvc/r"
+# PROP Intermediate_Dir "pd-msvc/r"
+# 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 "POOL_EXPORTS" /YX /FD /c
+# ADD CPP /nologo /W3 /GX /O2 /I "c:\programme\audio\pd\src" /I "f:\prog\max\flext\source" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D FLEXT_SYS=2 /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"
+# ADD RSC /l 0xc07 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# 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 /nologo /dll /machine:I386 /out:"pd-msvc/pool.dll" /libpath:"c:\programme\audio\pd\bin" /libpath:"f:\prog\max\flext\pd-msvc"
+
+!ELSEIF "$(CFG)" == "pool - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "Debug"
+# PROP BASE Intermediate_Dir "Debug"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "pd-msvc/d"
+# PROP Intermediate_Dir "pd-msvc/d"
+# 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 "POOL_EXPORTS" /YX /FD /GZ /c
+# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /I "c:\programme\audio\pd\src" /I "f:\prog\max\flext\source" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D FLEXT_SYS=2 /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"
+# ADD RSC /l 0xc07 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# 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"
+
+!ENDIF
+
+# Begin Target
+
+# Name "pool - Win32 Release"
+# Name "pool - Win32 Debug"
+# Begin Source File
+
+SOURCE=.\data.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\main.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\pool.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\pool.dtd
+# End Source File
+# Begin Source File
+
+SOURCE=.\pool.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\readme.txt
+# End Source File
+# End Target
+# End Project
diff --git a/externals/grill/vst/src/EditorThread.cpp b/externals/grill/vst/src/EditorThread.cpp
index 1761542c..bf955cf4 100644
--- a/externals/grill/vst/src/EditorThread.cpp
+++ b/externals/grill/vst/src/EditorThread.cpp
@@ -1,61 +1,61 @@
-// EditorThread.cpp : implementation file
-//
-
-#include "stdafx.h"
-#include "vst.h"
-#include "EditorThread.h"
-
-#ifdef _DEBUG
-#define new DEBUG_NEW
-#undef THIS_FILE
-static char THIS_FILE[] = __FILE__;
-#endif
-
-/////////////////////////////////////////////////////////////////////////////
-// CEditorThread
-
-IMPLEMENT_DYNCREATE(CEditorThread, CWinThread)
-
-CEditorThread::CEditorThread(): pop(NULL) {}
-
-CEditorThread::~CEditorThread() {}
-
-
-BOOL CEditorThread::InitInstance()
-{
- SetThreadPriority(THREAD_PRIORITY_LOWEST);
-
- m_pMainWnd = pop = new CPopupWindow;
- pop->SetPlugin( plug); // window class, size etc. is set here!
- return TRUE;
-}
-
-int CEditorThread::ExitInstance()
-{
- // TODO: perform any per-thread cleanup here
- return CWinThread::ExitInstance();
-}
-
-BEGIN_MESSAGE_MAP(CEditorThread, CWinThread)
- //{{AFX_MSG_MAP(CEditorThread)
- // NOTE - the ClassWizard will add and remove mapping macros here.
- //}}AFX_MSG_MAP
-END_MESSAGE_MAP()
-
-/////////////////////////////////////////////////////////////////////////////
-// CEditorThread message handlers
-
-void CEditorThread::SetPlugin(VSTPlugin *p)
-{
- plug = p;
-}
-
-void CEditorThread::Close()
-{
- if(pop) pop->SendMessage(WM_CLOSE);
-}
-
-void CEditorThread::Show(bool show)
-{
- if(pop) pop->ShowWindow(show);
+// EditorThread.cpp : implementation file
+//
+
+#include "stdafx.h"
+#include "vst.h"
+#include "EditorThread.h"
+
+#ifdef _DEBUG
+#define new DEBUG_NEW
+#undef THIS_FILE
+static char THIS_FILE[] = __FILE__;
+#endif
+
+/////////////////////////////////////////////////////////////////////////////
+// CEditorThread
+
+IMPLEMENT_DYNCREATE(CEditorThread, CWinThread)
+
+CEditorThread::CEditorThread(): pop(NULL) {}
+
+CEditorThread::~CEditorThread() {}
+
+
+BOOL CEditorThread::InitInstance()
+{
+ // SetThreadPriority(THREAD_PRIORITY_LOWEST);
+
+ m_pMainWnd = pop = new CPopupWindow;
+ pop->SetPlugin( plug); // window class, size etc. is set here!
+ return TRUE;
+}
+
+int CEditorThread::ExitInstance()
+{
+ // TODO: perform any per-thread cleanup here
+ return CWinThread::ExitInstance();
+}
+
+BEGIN_MESSAGE_MAP(CEditorThread, CWinThread)
+ //{{AFX_MSG_MAP(CEditorThread)
+ // NOTE - the ClassWizard will add and remove mapping macros here.
+ //}}AFX_MSG_MAP
+END_MESSAGE_MAP()
+
+/////////////////////////////////////////////////////////////////////////////
+// CEditorThread message handlers
+
+void CEditorThread::SetPlugin(VSTPlugin *p)
+{
+ plug = p;
+}
+
+void CEditorThread::Close()
+{
+ if(pop) pop->SendMessage(WM_CLOSE);
+}
+
+void CEditorThread::Show(bool show)
+{
+ if(pop) pop->ShowWindow(show);
} \ No newline at end of file
diff --git a/externals/grill/vst/src/VstHost.cpp b/externals/grill/vst/src/VstHost.cpp
index f2d96763..8e6f2eb4 100644
--- a/externals/grill/vst/src/VstHost.cpp
+++ b/externals/grill/vst/src/VstHost.cpp
@@ -1,541 +1,541 @@
-#include "stdafx.h"
-#include "EditorThread.h"
-#include "VstHost.h"
-#include "PopupWindow.h"
-#include "vst\aeffeditor.h"
-#include "vst\aeffectx.h"
-
-
-VstTimeInfo VSTPlugin::_timeInfo;
-
-float VSTPlugin::sample_rate = 44100;
-
-
-extern "C" void post(char *fmt, ...);
-
-////////////////////
-//
-/////////////////////
-VSTPlugin::VSTPlugin():
- posx(0),posy(0),
- _editor(false)
-{
- queue_size=0;
- _sDllName = NULL;
- h_dll=NULL;
- instantiated=false; // Constructin' with no instance
- overwrite = false;
- w = GetForegroundWindow();
-// show_params = false;
- _midichannel = 0;
- edited = false;
-}
-
-VSTPlugin::~VSTPlugin()
-{
- Free(); // Call free
- delete _sDllName; // if _sDllName = NULL , the operation does nothing -> it's safe.
-}
-
-int VSTPlugin::Instance( const char *dllname)
-{
- h_dll=LoadLibrary(dllname);
-
- if(h_dll==NULL)
- {
- return VSTINSTANCE_ERR_NO_VALID_FILE;
- }
-// post("Loaded library %s" , dllname);
- PVSTMAIN main = (PVSTMAIN)GetProcAddress(h_dll,"main");
- if(!main)
- {
- FreeLibrary(h_dll);
- _pEffect=NULL;
- instantiated=false;
- return VSTINSTANCE_ERR_NO_VST_PLUGIN;
- }
- //post("Found main function - about to call it");
- //This calls the "main" function and receives the pointer to the AEffect structure.
- _pEffect = main((audioMasterCallback)&(this->Master));
-
- if(!_pEffect)
- {
- post("VST plugin : unable to create effect");
- FreeLibrary(h_dll);
- _pEffect=NULL;
- instantiated=false;
- return VSTINSTANCE_ERR_REJECTED;
- }
-
- if( _pEffect->magic!=kEffectMagic)
- {
- post("VST plugin : Instance query rejected by 0x%.8X\n",(int)_pEffect);
- FreeLibrary(h_dll);
- _pEffect=NULL;
- instantiated=false;
- return VSTINSTANCE_ERR_REJECTED;
- }
-
- //post("VST plugin : Instanced at (Effect*): %.8X\n",(int)_pEffect);
-
- //init plugin
- _pEffect->user = this;
- Dispatch( effOpen , 0, 0, NULL, 0.0f);
- Dispatch( effSetProgram , 0, 0, NULL, 0.0f);
-// Dispatch( effMainsChanged, 0, 1, NULL, 0.0f);
-
- //************************************set samplerate and stream size here
- // we get it when we init our DSP
-
-// Dispatch( effSetSampleRate, 0, 0, NULL, (float)Global::pConfig->_pOutputDriver->_samplesPerSec);
-// Dispatch( effSetBlockSize, 0, STREAM_SIZE, NULL, 0.0f);
-
-
- if (!Dispatch( effGetProductString, 0, 0, &_sProductName, 0.0f))
- {
- CString str1(dllname);
- CString str2 = str1.Mid(str1.ReverseFind('\\')+1);
- int snip = str2.Find('.');
- if ( snip != -1 )
- {
- str1 = str2.Left( snip );
- }
- else
- {
- str1 = str2;
- }
- strcpy(_sProductName,str1);
-
- }
-
- if (!_pEffect->dispatcher(_pEffect, effGetVendorString, 0, 0, &_sVendorName, 0.0f))
- {
- strcpy(_sVendorName, "Unknown vendor");
- }
- _version = _pEffect->version;
- _isSynth = (_pEffect->flags & effFlagsIsSynth)?true:false;
- overwrite = (_pEffect->flags & effFlagsCanReplacing)?true:false;
- _editor = (_pEffect->flags & effFlagsHasEditor)?true:false;
-
- if ( _sDllName != NULL ) delete _sDllName;
- _sDllName = new char[strlen(dllname)+1];
- sprintf(_sDllName,dllname);
-
-
-
-
- //keep plugin name
- instantiated=true;
-
- return VSTINSTANCE_NO_ERROR;
-}
-
-int VSTPlugin::getNumInputs( void )
-{
- return _pEffect->numInputs;
-}
-
-int VSTPlugin::getNumOutputs( void )
-{
- return _pEffect->numOutputs;
-}
-
-
-void VSTPlugin::Create(VSTPlugin *plug)
-{
- h_dll=plug->h_dll;
- _pEffect=plug->_pEffect;
- _pEffect->user=this;
- Dispatch( effMainsChanged, 0, 1, NULL, 0.0f);
-// strcpy(_editName,plug->_editName); On current implementation, this replaces the right one.
- strcpy(_sProductName,plug->_sProductName);
- strcpy(_sVendorName,plug->_sVendorName);
-
- _sDllName = new char[strlen(plug->_sDllName)+1];
- strcpy(_sDllName,plug->_sDllName);
-
- _isSynth=plug->_isSynth;
- _version=plug->_version;
-
- plug->instantiated=false; // We are "stoling" the plugin from the "plug" object so this
- // is just a "trick" so that when destructing the "plug", it
- // doesn't unload the Dll.
- instantiated=true;
-}
-
-void VSTPlugin::Free() // Called also in destruction
-{
- if(instantiated)
- {
- instantiated=false;
- post("VST plugin : Free query 0x%.8X\n",(int)_pEffect);
- _pEffect->user = NULL;
- Dispatch( effMainsChanged, 0, 0, NULL, 0.0f);
- Dispatch( effClose, 0, 0, NULL, 0.0f);
-// delete _pEffect; // <- Should check for the necessity of this command.
- _pEffect=NULL;
- FreeLibrary(h_dll);
- }
-}
-
-void VSTPlugin::Init( float samplerate , float blocksize )
-{
- sample_rate = samplerate;
- Dispatch(effOpen , 0, 0, NULL, 0.f);
- Dispatch(effMainsChanged, 0, 1, NULL, 0.f);
- Dispatch(effSetSampleRate, 0, 0, 0, (float) sample_rate );
- Dispatch(effSetBlockSize, 0, blocksize, NULL, 0.f );
-}
-
-
-bool VSTPlugin::DescribeValue(int p,char* psTxt)
-{
- int parameter = p;
- if(instantiated)
- {
- if(parameter<_pEffect->numParams)
- {
-// char par_name[64];
- char par_display[64];
- char par_label[64];
-
-// Dispatch(effGetParamName,parameter,0,par_name,0.0f);
- Dispatch(effGetParamDisplay,parameter,0,par_display,0.0f);
- Dispatch(effGetParamLabel,parameter,0,par_label,0.0f);
-// sprintf(psTxt,"%s:%s%s",par_name,par_display,par_label);
- sprintf(psTxt,"%s%s",par_display,par_label);
- return true;
- }
- else sprintf(psTxt,"NumParams Exeeded");
- }
- else sprintf(psTxt,"Not loaded");
-
- return false;
-}
-
-bool VSTPlugin::SetParameter(int parameter, float value)
-{
- if(instantiated)
- {
- if (( parameter >= 0 ) && (parameter<=_pEffect->numParams))
- {
- _pEffect->setParameter(_pEffect,parameter,value);
- return true;
- }
- }
-
- return false;
-}
-
-bool VSTPlugin::SetParameter(int parameter, int value)
-{
- return SetParameter(parameter,value/65535.0f);
-}
-
-int VSTPlugin::GetCurrentProgram()
-{
- if(instantiated)
- return Dispatch(effGetProgram,0,0,NULL,0.0f);
- else
- return 0;
-}
-
-void VSTPlugin::SetCurrentProgram(int prg)
-{
- if(instantiated)
- Dispatch(effSetProgram,0,prg,NULL,0.0f);
-}
-
-bool VSTPlugin::AddMIDI(unsigned char data0,unsigned char data1,unsigned char data2)
-{
- if (instantiated)
- {
- VstMidiEvent* pevent=&midievent[queue_size];
-
- pevent->type = kVstMidiType;
- pevent->byteSize = 24;
- pevent->deltaFrames = 0;
- pevent->flags = 0;
- pevent->detune = 0;
- pevent->noteLength = 0;
- pevent->noteOffset = 0;
- pevent->reserved1 = 0;
- pevent->reserved2 = 0;
- pevent->noteOffVelocity = 0;
- pevent->midiData[0] = data0;
- pevent->midiData[1] = data1;
- pevent->midiData[2] = data2;
- pevent->midiData[3] = 0;
-
- if ( queue_size < MAX_EVENTS ) queue_size++;
- SendMidi();
- return true;
- }
- else return false;
-}
-
-
-void VSTPlugin::SendMidi()
-{
- if(/*instantiated &&*/ queue_size>0)
- {
- // Prepare MIDI events and free queue dispatching all events
- events.numEvents = queue_size;
- events.reserved = 0;
- for(int q=0;q<queue_size;q++) events.events[q] = (VstEvent*)&midievent[q];
-
- Dispatch(effProcessEvents, 0, 0, &events, 0.0f);
- queue_size=0;
- }
-}
-
-
-void VSTPlugin::processReplacing( float **inputs, float **outputs, long sampleframes )
-{
- _pEffect->processReplacing( _pEffect , inputs , outputs , sampleframes );
-
-}
-
-void VSTPlugin::process( float **inputs, float **outputs, long sampleframes )
-{
- _pEffect->process( _pEffect , inputs , outputs , sampleframes );
-}
-
-
-// Host callback dispatcher
-long VSTPlugin::Master(AEffect *effect, long opcode, long index, long value, void *ptr, float opt)
-{
- //post("VST plugin call to host dispatcher: Eff: 0x%.8X, Opcode = %d, Index = %d, Value = %d, PTR = %.8X, OPT = %.3f\n",(int)effect, opcode,index,value,(int)ptr,opt);
- //st( "audioMasterWantMidi %d " , audioMasterWantMidi);
-
- // Support opcodes
- switch(opcode)
- {
- case audioMasterAutomate:
- return 0; // index, value, returns 0
-
- case audioMasterVersion:
- return 9; // vst version, currently 7 (0 for older)
-
- case audioMasterCurrentId:
- return 'AASH'; // returns the unique id of a plug that's currently loading
-
- case audioMasterIdle:
- effect->dispatcher(effect, effEditIdle, 0, 0, NULL, 0.0f);
- return 0; // call application idle routine (this will call effEditIdle for all open editors too)
-
- case audioMasterPinConnected:
- return false; // inquire if an input or output is beeing connected;
-
- case audioMasterWantMidi:
- return 0;
-
- case audioMasterProcessEvents:
- return 0; // Support of vst events to host is not available
-
- case audioMasterGetTime:
- memset(&_timeInfo, 0, sizeof(_timeInfo));
- _timeInfo.samplePos = 0;
- _timeInfo.sampleRate = sample_rate;
- return (long)&_timeInfo;
-
-
- case audioMasterTempoAt:
- return 0;
-
- case audioMasterNeedIdle:
- effect->dispatcher(effect, effIdle, 0, 0, NULL, 0.0f);
- return 1;
-
- case audioMasterGetSampleRate:
- return sample_rate;
-
- case audioMasterGetVendorString: // Just fooling version string
- strcpy((char*)ptr,"Steinberg");
- return 0;
-
- case audioMasterGetVendorVersion:
- return 5000; // HOST version 5000
-
- case audioMasterGetProductString: // Just fooling product string
- strcpy((char*)ptr,"Cubase 5.0");
- return 0;
-
- case audioMasterVendorSpecific:
- {
- return 0;
- }
-
-
- case audioMasterGetLanguage:
- return kVstLangEnglish;
-
- case audioMasterUpdateDisplay:
- post("audioMasterUpdateDisplay");
- effect->dispatcher(effect, effEditIdle, 0, 0, NULL, 0.0f);
- return 0;
-
-
- case audioMasterSetTime: post("VST master dispatcher: Set Time");break;
- case audioMasterGetNumAutomatableParameters: post("VST master dispatcher: GetNumAutPar");break;
- case audioMasterGetParameterQuantization: post("VST master dispatcher: ParamQuant");break;
- case audioMasterIOChanged: post("VST master dispatcher: IOchanged");break;
- case audioMasterSizeWindow: post("VST master dispatcher: Size Window");break;
- case audioMasterGetBlockSize: post("VST master dispatcher: GetBlockSize");break;
- case audioMasterGetInputLatency: post("VST master dispatcher: GetInLatency");break;
- case audioMasterGetOutputLatency: post("VST master dispatcher: GetOutLatency");break;
- case audioMasterGetPreviousPlug: post("VST master dispatcher: PrevPlug");break;
- case audioMasterGetNextPlug: post("VST master dispatcher: NextPlug");break;
- case audioMasterWillReplaceOrAccumulate: post("VST master dispatcher: WillReplace"); break;
- case audioMasterGetCurrentProcessLevel: return 0; break;
- case audioMasterGetAutomationState: post("VST master dispatcher: GetAutState");break;
- case audioMasterOfflineStart: post("VST master dispatcher: Offlinestart");break;
- case audioMasterOfflineRead: post("VST master dispatcher: Offlineread");break;
- case audioMasterOfflineWrite: post("VST master dispatcher: Offlinewrite");break;
- case audioMasterOfflineGetCurrentPass: post("VST master dispatcher: OfflineGetcurrentpass");break;
- case audioMasterOfflineGetCurrentMetaPass: post("VST master dispatcher: GetGetCurrentMetapass");break;
- case audioMasterSetOutputSampleRate: post("VST master dispatcher: Setsamplerate");break;
- case audioMasterGetSpeakerArrangement: post("VST master dispatcher: Getspeaker");break;
- case audioMasterSetIcon: post("VST master dispatcher: seticon");break;
- case audioMasterCanDo: post("VST master dispatcher: Can Do");break;
- case audioMasterOpenWindow: post("VST master dispatcher: OpenWindow");break;
- case audioMasterCloseWindow: post("VST master dispatcher: CloseWindow");break;
- case audioMasterGetDirectory: post("VST master dispatcher: GetDirectory");break;
-// case audioMasterUpdateDisplay: post("VST master dispatcher: audioMasterUpdateDisplay");break;
-
- default: post("VST master dispatcher: undefed: %d , %d",opcode , effKeysRequired ) ;break;
- }
-
- return 0;
-}
-
-bool VSTPlugin::AddNoteOn( unsigned char note,unsigned char speed,unsigned char midichannel)
-{
- return AddMIDI((char)MIDI_NOTEON | midichannel,note,speed);
-}
-
-bool VSTPlugin::AddNoteOff( unsigned char note,unsigned char midichannel)
-{
- return AddMIDI((char)MIDI_NOTEOFF | midichannel,note,0);
-}
-
-
-bool VSTPlugin::replace()
-{
- return overwrite;
-}
-
-
-void VSTPlugin::edit(bool open)
-{
- if(instantiated) {
- if(open) {
- if ( HasEditor() && !edited) {
- edited = true;
- b = new CEditorThread();
- b->SetPlugin( this);
- b->CreateThread();
- }
- }
- else {
- if (HasEditor() && edited) b->Close();
- }
- }
-}
-
-void VSTPlugin::visible(bool vis)
-{
- if(instantiated && edited) b->Show(vis);
-}
-
-void VSTPlugin::EditorIdle()
-{
- Dispatch(effEditIdle,0,0, w,0.0f);
-}
-
-RECT VSTPlugin::GetEditorRect()
-{
- RECT ret;
- ERect *r;
- Dispatch(effEditGetRect,0,0, &r,0.0f);
- ret.top = r->top;
- ret.bottom = r->bottom;
- ret.left = r->left;
- ret.right = r->right;
- return ret;
-}
-
-void VSTPlugin::SetEditWindow(HWND h)
-{
- w = h;
- Dispatch(effEditOpen,0,0, w,0.0f);
-}
-
-void VSTPlugin::OnEditorClose()
-{
- Dispatch(effEditClose,0,0, w,0.0f);
-}
-
-/*
-void VSTPlugin::SetShowParameters(bool s)
-{
- show_params = s;
-}
-
-bool VSTPlugin::ShowParams()
-{
- return show_params;
-}
-*/
-
-void VSTPlugin::AddAftertouch(int value)
-{
- if (value < 0) value = 0; else if (value > 127) value = 127;
- AddMIDI( (char)MIDI_NOTEOFF | _midichannel , value );
-}
-
-void VSTPlugin::AddPitchBend(int value)
-{
- AddMIDI( MIDI_PITCHBEND + (_midichannel & 0xf) , ((value>>7) & 127), (value & 127));
-}
-
-void VSTPlugin::AddProgramChange(int value)
-{
- if (value < 0) value = 0; else if (value > 127) value = 127;
- AddMIDI( MIDI_PROGRAMCHANGE + (_midichannel & 0xf), value, 0);
-}
-
-void VSTPlugin::AddControlChange(int control, int value)
-{
- if (control < 0) control = 0; else if (control > 127) control = 127;
- if (value < 0) value = 0; else if (value > 127) value = 127;
- AddMIDI( MIDI_CONTROLCHANGE + (_midichannel & 0xf), control, value);
-}
-
-
-bool VSTPlugin::GetProgramName( int cat , int p, char *buf)
-{
- int parameter = p;
- if(instantiated)
- {
- if(parameter<NumPrograms())
- {
- Dispatch(effGetProgramNameIndexed,parameter,cat,buf,0.0f);
- return true;
- }
- }
- return false;
-}
-
-int VSTPlugin::GetNumCategories()
-{
- if(instantiated)
- return Dispatch(effGetNumProgramCategories,0,0,NULL,0.0f);
- else
- return 0;
-}
-
-void VSTPlugin::StopEditing()
-{
- edited = false;
-}
+#include "stdafx.h"
+#include "EditorThread.h"
+#include "VstHost.h"
+#include "PopupWindow.h"
+#include "vst\aeffeditor.h"
+#include "vst\aeffectx.h"
+
+
+VstTimeInfo VSTPlugin::_timeInfo;
+
+float VSTPlugin::sample_rate = 44100;
+
+
+extern "C" void post(char *fmt, ...);
+
+////////////////////
+//
+/////////////////////
+VSTPlugin::VSTPlugin():
+ posx(0),posy(0),
+ _editor(false)
+{
+ queue_size=0;
+ _sDllName = NULL;
+ h_dll=NULL;
+ instantiated=false; // Constructin' with no instance
+ overwrite = false;
+ w = GetForegroundWindow();
+// show_params = false;
+ _midichannel = 0;
+ edited = false;
+}
+
+VSTPlugin::~VSTPlugin()
+{
+ Free(); // Call free
+ delete _sDllName; // if _sDllName = NULL , the operation does nothing -> it's safe.
+}
+
+int VSTPlugin::Instance( const char *dllname)
+{
+ h_dll=LoadLibrary(dllname);
+
+ if(h_dll==NULL)
+ {
+ return VSTINSTANCE_ERR_NO_VALID_FILE;
+ }
+// post("Loaded library %s" , dllname);
+ PVSTMAIN main = (PVSTMAIN)GetProcAddress(h_dll,"main");
+ if(!main)
+ {
+ FreeLibrary(h_dll);
+ _pEffect=NULL;
+ instantiated=false;
+ return VSTINSTANCE_ERR_NO_VST_PLUGIN;
+ }
+ //post("Found main function - about to call it");
+ //This calls the "main" function and receives the pointer to the AEffect structure.
+ _pEffect = main((audioMasterCallback)&(this->Master));
+
+ if(!_pEffect)
+ {
+ post("VST plugin : unable to create effect");
+ FreeLibrary(h_dll);
+ _pEffect=NULL;
+ instantiated=false;
+ return VSTINSTANCE_ERR_REJECTED;
+ }
+
+ if( _pEffect->magic!=kEffectMagic)
+ {
+ post("VST plugin : Instance query rejected by 0x%.8X\n",(int)_pEffect);
+ FreeLibrary(h_dll);
+ _pEffect=NULL;
+ instantiated=false;
+ return VSTINSTANCE_ERR_REJECTED;
+ }
+
+ //post("VST plugin : Instanced at (Effect*): %.8X\n",(int)_pEffect);
+
+ //init plugin
+ _pEffect->user = this;
+ Dispatch( effOpen , 0, 0, NULL, 0.0f);
+ Dispatch( effSetProgram , 0, 0, NULL, 0.0f);
+// Dispatch( effMainsChanged, 0, 1, NULL, 0.0f);
+
+ //************************************set samplerate and stream size here
+ // we get it when we init our DSP
+
+// Dispatch( effSetSampleRate, 0, 0, NULL, (float)Global::pConfig->_pOutputDriver->_samplesPerSec);
+// Dispatch( effSetBlockSize, 0, STREAM_SIZE, NULL, 0.0f);
+
+
+ if (!Dispatch( effGetProductString, 0, 0, &_sProductName, 0.0f))
+ {
+ CString str1(dllname);
+ CString str2 = str1.Mid(str1.ReverseFind('\\')+1);
+ int snip = str2.Find('.');
+ if ( snip != -1 )
+ {
+ str1 = str2.Left( snip );
+ }
+ else
+ {
+ str1 = str2;
+ }
+ strcpy(_sProductName,str1);
+
+ }
+
+ if (!_pEffect->dispatcher(_pEffect, effGetVendorString, 0, 0, &_sVendorName, 0.0f))
+ {
+ strcpy(_sVendorName, "Unknown vendor");
+ }
+ _version = _pEffect->version;
+ _isSynth = (_pEffect->flags & effFlagsIsSynth)?true:false;
+ overwrite = (_pEffect->flags & effFlagsCanReplacing)?true:false;
+ _editor = (_pEffect->flags & effFlagsHasEditor)?true:false;
+
+ if ( _sDllName != NULL ) delete _sDllName;
+ _sDllName = new char[strlen(dllname)+1];
+ sprintf(_sDllName,dllname);
+
+
+
+
+ //keep plugin name
+ instantiated=true;
+
+ return VSTINSTANCE_NO_ERROR;
+}
+
+int VSTPlugin::getNumInputs( void )
+{
+ return _pEffect->numInputs;
+}
+
+int VSTPlugin::getNumOutputs( void )
+{
+ return _pEffect->numOutputs;
+}
+
+
+void VSTPlugin::Create(VSTPlugin *plug)
+{
+ h_dll=plug->h_dll;
+ _pEffect=plug->_pEffect;
+ _pEffect->user=this;
+ Dispatch( effMainsChanged, 0, 1, NULL, 0.0f);
+// strcpy(_editName,plug->_editName); On current implementation, this replaces the right one.
+ strcpy(_sProductName,plug->_sProductName);
+ strcpy(_sVendorName,plug->_sVendorName);
+
+ _sDllName = new char[strlen(plug->_sDllName)+1];
+ strcpy(_sDllName,plug->_sDllName);
+
+ _isSynth=plug->_isSynth;
+ _version=plug->_version;
+
+ plug->instantiated=false; // We are "stoling" the plugin from the "plug" object so this
+ // is just a "trick" so that when destructing the "plug", it
+ // doesn't unload the Dll.
+ instantiated=true;
+}
+
+void VSTPlugin::Free() // Called also in destruction
+{
+ if(instantiated)
+ {
+ instantiated=false;
+ post("VST plugin : Free query 0x%.8X\n",(int)_pEffect);
+ _pEffect->user = NULL;
+ Dispatch( effMainsChanged, 0, 0, NULL, 0.0f);
+ Dispatch( effClose, 0, 0, NULL, 0.0f);
+// delete _pEffect; // <- Should check for the necessity of this command.
+ _pEffect=NULL;
+ FreeLibrary(h_dll);
+ }
+}
+
+void VSTPlugin::Init( float samplerate , float blocksize )
+{
+ sample_rate = samplerate;
+ Dispatch(effOpen , 0, 0, NULL, 0.f);
+ Dispatch(effMainsChanged, 0, 1, NULL, 0.f);
+ Dispatch(effSetSampleRate, 0, 0, 0, (float) sample_rate );
+ Dispatch(effSetBlockSize, 0, blocksize, NULL, 0.f );
+}
+
+
+bool VSTPlugin::DescribeValue(int p,char* psTxt)
+{
+ int parameter = p;
+ if(instantiated)
+ {
+ if(parameter<_pEffect->numParams)
+ {
+// char par_name[64];
+ char par_display[64];
+ char par_label[64];
+
+// Dispatch(effGetParamName,parameter,0,par_name,0.0f);
+ Dispatch(effGetParamDisplay,parameter,0,par_display,0.0f);
+ Dispatch(effGetParamLabel,parameter,0,par_label,0.0f);
+// sprintf(psTxt,"%s:%s%s",par_name,par_display,par_label);
+ sprintf(psTxt,"%s%s",par_display,par_label);
+ return true;
+ }
+ else sprintf(psTxt,"NumParams Exeeded");
+ }
+ else sprintf(psTxt,"Not loaded");
+
+ return false;
+}
+
+bool VSTPlugin::SetParameter(int parameter, float value)
+{
+ if(instantiated)
+ {
+ if (( parameter >= 0 ) && (parameter<=_pEffect->numParams))
+ {
+ _pEffect->setParameter(_pEffect,parameter,value);
+ return true;
+ }
+ }
+
+ return false;
+}
+
+bool VSTPlugin::SetParameter(int parameter, int value)
+{
+ return SetParameter(parameter,value/65535.0f);
+}
+
+int VSTPlugin::GetCurrentProgram()
+{
+ if(instantiated)
+ return Dispatch(effGetProgram,0,0,NULL,0.0f);
+ else
+ return 0;
+}
+
+void VSTPlugin::SetCurrentProgram(int prg)
+{
+ if(instantiated)
+ Dispatch(effSetProgram,0,prg,NULL,0.0f);
+}
+
+bool VSTPlugin::AddMIDI(unsigned char data0,unsigned char data1,unsigned char data2)
+{
+ if (instantiated)
+ {
+ VstMidiEvent* pevent=&midievent[queue_size];
+
+ pevent->type = kVstMidiType;
+ pevent->byteSize = 24;
+ pevent->deltaFrames = 0;
+ pevent->flags = 0;
+ pevent->detune = 0;
+ pevent->noteLength = 0;
+ pevent->noteOffset = 0;
+ pevent->reserved1 = 0;
+ pevent->reserved2 = 0;
+ pevent->noteOffVelocity = 0;
+ pevent->midiData[0] = data0;
+ pevent->midiData[1] = data1;
+ pevent->midiData[2] = data2;
+ pevent->midiData[3] = 0;
+
+ if ( queue_size < MAX_EVENTS ) queue_size++;
+ SendMidi();
+ return true;
+ }
+ else return false;
+}
+
+
+void VSTPlugin::SendMidi()
+{
+ if(/*instantiated &&*/ queue_size>0)
+ {
+ // Prepare MIDI events and free queue dispatching all events
+ events.numEvents = queue_size;
+ events.reserved = 0;
+ for(int q=0;q<queue_size;q++) events.events[q] = (VstEvent*)&midievent[q];
+
+ Dispatch(effProcessEvents, 0, 0, &events, 0.0f);
+ queue_size=0;
+ }
+}
+
+
+void VSTPlugin::processReplacing( float **inputs, float **outputs, long sampleframes )
+{
+ _pEffect->processReplacing( _pEffect , inputs , outputs , sampleframes );
+
+}
+
+void VSTPlugin::process( float **inputs, float **outputs, long sampleframes )
+{
+ _pEffect->process( _pEffect , inputs , outputs , sampleframes );
+}
+
+
+// Host callback dispatcher
+long VSTPlugin::Master(AEffect *effect, long opcode, long index, long value, void *ptr, float opt)
+{
+ post("VST plugin call to host dispatcher: Eff: 0x%.8X, Opcode = %d, Index = %d, Value = %d, PTR = %.8X, OPT = %.3f\n",(int)effect, opcode,index,value,(int)ptr,opt);
+ //st( "audioMasterWantMidi %d " , audioMasterWantMidi);
+
+ // Support opcodes
+ switch(opcode)
+ {
+ case audioMasterAutomate:
+ return 0; // index, value, returns 0
+
+ case audioMasterVersion:
+ return 9; // vst version, currently 7 (0 for older)
+
+ case audioMasterCurrentId:
+ return 'AASH'; // returns the unique id of a plug that's currently loading
+
+ case audioMasterIdle:
+ effect->dispatcher(effect, effEditIdle, 0, 0, NULL, 0.0f);
+ return 0; // call application idle routine (this will call effEditIdle for all open editors too)
+
+ case audioMasterPinConnected:
+ return false; // inquire if an input or output is beeing connected;
+
+ case audioMasterWantMidi:
+ return 0;
+
+ case audioMasterProcessEvents:
+ return 0; // Support of vst events to host is not available
+
+ case audioMasterGetTime:
+ memset(&_timeInfo, 0, sizeof(_timeInfo));
+ _timeInfo.samplePos = 0;
+ _timeInfo.sampleRate = sample_rate;
+ return (long)&_timeInfo;
+
+
+ case audioMasterTempoAt:
+ return 0;
+
+ case audioMasterNeedIdle:
+ effect->dispatcher(effect, effIdle, 0, 0, NULL, 0.0f);
+ return 1;
+
+ case audioMasterGetSampleRate:
+ return sample_rate;
+
+ case audioMasterGetVendorString: // Just fooling version string
+ strcpy((char*)ptr,"Steinberg");
+ return 0;
+
+ case audioMasterGetVendorVersion:
+ return 5000; // HOST version 5000
+
+ case audioMasterGetProductString: // Just fooling product string
+ strcpy((char*)ptr,"Cubase 5.0");
+ return 0;
+
+ case audioMasterVendorSpecific:
+ {
+ return 0;
+ }
+
+
+ case audioMasterGetLanguage:
+ return kVstLangEnglish;
+
+ case audioMasterUpdateDisplay:
+ post("audioMasterUpdateDisplay");
+ effect->dispatcher(effect, effEditIdle, 0, 0, NULL, 0.0f);
+ return 0;
+
+
+ case audioMasterSetTime: post("VST master dispatcher: Set Time");break;
+ case audioMasterGetNumAutomatableParameters: post("VST master dispatcher: GetNumAutPar");break;
+ case audioMasterGetParameterQuantization: post("VST master dispatcher: ParamQuant");break;
+ case audioMasterIOChanged: post("VST master dispatcher: IOchanged");break;
+ case audioMasterSizeWindow: post("VST master dispatcher: Size Window");break;
+ case audioMasterGetBlockSize: post("VST master dispatcher: GetBlockSize");break;
+ case audioMasterGetInputLatency: post("VST master dispatcher: GetInLatency");break;
+ case audioMasterGetOutputLatency: post("VST master dispatcher: GetOutLatency");break;
+ case audioMasterGetPreviousPlug: post("VST master dispatcher: PrevPlug");break;
+ case audioMasterGetNextPlug: post("VST master dispatcher: NextPlug");break;
+ case audioMasterWillReplaceOrAccumulate: post("VST master dispatcher: WillReplace"); break;
+ case audioMasterGetCurrentProcessLevel: return 0; break;
+ case audioMasterGetAutomationState: post("VST master dispatcher: GetAutState");break;
+ case audioMasterOfflineStart: post("VST master dispatcher: Offlinestart");break;
+ case audioMasterOfflineRead: post("VST master dispatcher: Offlineread");break;
+ case audioMasterOfflineWrite: post("VST master dispatcher: Offlinewrite");break;
+ case audioMasterOfflineGetCurrentPass: post("VST master dispatcher: OfflineGetcurrentpass");break;
+ case audioMasterOfflineGetCurrentMetaPass: post("VST master dispatcher: GetGetCurrentMetapass");break;
+ case audioMasterSetOutputSampleRate: post("VST master dispatcher: Setsamplerate");break;
+ case audioMasterGetSpeakerArrangement: post("VST master dispatcher: Getspeaker");break;
+ case audioMasterSetIcon: post("VST master dispatcher: seticon");break;
+ case audioMasterCanDo: post("VST master dispatcher: Can Do");break;
+ case audioMasterOpenWindow: post("VST master dispatcher: OpenWindow");break;
+ case audioMasterCloseWindow: post("VST master dispatcher: CloseWindow");break;
+ case audioMasterGetDirectory: post("VST master dispatcher: GetDirectory");break;
+// case audioMasterUpdateDisplay: post("VST master dispatcher: audioMasterUpdateDisplay");break;
+
+ default: post("VST master dispatcher: undefed: %d , %d",opcode , effKeysRequired ) ;break;
+ }
+
+ return 0;
+}
+
+bool VSTPlugin::AddNoteOn( unsigned char note,unsigned char speed,unsigned char midichannel)
+{
+ return AddMIDI((char)MIDI_NOTEON | midichannel,note,speed);
+}
+
+bool VSTPlugin::AddNoteOff( unsigned char note,unsigned char midichannel)
+{
+ return AddMIDI((char)MIDI_NOTEOFF | midichannel,note,0);
+}
+
+
+bool VSTPlugin::replace()
+{
+ return overwrite;
+}
+
+
+void VSTPlugin::edit(bool open)
+{
+ if(instantiated) {
+ if(open) {
+ if ( HasEditor() && !edited) {
+ edited = true;
+ b = new CEditorThread();
+ b->SetPlugin( this);
+ b->CreateThread();
+ }
+ }
+ else {
+ if (HasEditor() && edited) b->Close();
+ }
+ }
+}
+
+void VSTPlugin::visible(bool vis)
+{
+ if(instantiated && edited) b->Show(vis);
+}
+
+void VSTPlugin::EditorIdle()
+{
+ Dispatch(effEditIdle,0,0, w,0.0f);
+}
+
+RECT VSTPlugin::GetEditorRect()
+{
+ RECT ret;
+ ERect *r;
+ Dispatch(effEditGetRect,0,0, &r,0.0f);
+ ret.top = r->top;
+ ret.bottom = r->bottom;
+ ret.left = r->left;
+ ret.right = r->right;
+ return ret;
+}
+
+void VSTPlugin::SetEditWindow(HWND h)
+{
+ w = h;
+ Dispatch(effEditOpen,0,0, w,0.0f);
+}
+
+void VSTPlugin::OnEditorClose()
+{
+ Dispatch(effEditClose,0,0, w,0.0f);
+}
+
+/*
+void VSTPlugin::SetShowParameters(bool s)
+{
+ show_params = s;
+}
+
+bool VSTPlugin::ShowParams()
+{
+ return show_params;
+}
+*/
+
+void VSTPlugin::AddAftertouch(int value)
+{
+ if (value < 0) value = 0; else if (value > 127) value = 127;
+ AddMIDI( (char)MIDI_NOTEOFF | _midichannel , value );
+}
+
+void VSTPlugin::AddPitchBend(int value)
+{
+ AddMIDI( MIDI_PITCHBEND + (_midichannel & 0xf) , ((value>>7) & 127), (value & 127));
+}
+
+void VSTPlugin::AddProgramChange(int value)
+{
+ if (value < 0) value = 0; else if (value > 127) value = 127;
+ AddMIDI( MIDI_PROGRAMCHANGE + (_midichannel & 0xf), value, 0);
+}
+
+void VSTPlugin::AddControlChange(int control, int value)
+{
+ if (control < 0) control = 0; else if (control > 127) control = 127;
+ if (value < 0) value = 0; else if (value > 127) value = 127;
+ AddMIDI( MIDI_CONTROLCHANGE + (_midichannel & 0xf), control, value);
+}
+
+
+bool VSTPlugin::GetProgramName( int cat , int p, char *buf)
+{
+ int parameter = p;
+ if(instantiated)
+ {
+ if(parameter<NumPrograms())
+ {
+ Dispatch(effGetProgramNameIndexed,parameter,cat,buf,0.0f);
+ return true;
+ }
+ }
+ return false;
+}
+
+int VSTPlugin::GetNumCategories()
+{
+ if(instantiated)
+ return Dispatch(effGetNumProgramCategories,0,0,NULL,0.0f);
+ else
+ return 0;
+}
+
+void VSTPlugin::StopEditing()
+{
+ edited = false;
+}
diff --git a/externals/grill/xsample/xsample.cw b/externals/grill/xsample/xsample.cw
index 70783c4d..71f32471 100755
--- a/externals/grill/xsample/xsample.cw
+++ b/externals/grill/xsample/xsample.cw
Binary files differ