From f128374bfd1869bde1f22d4f80b6267c99b507a7 Mon Sep 17 00:00:00 2001 From: Thomas Grill Date: Wed, 26 Feb 2003 04:40:35 +0000 Subject: "" svn path=/trunk/; revision=433 --- externals/grill/dyn/config-pd-linux.txt | 2 +- externals/grill/dyn/src/main.cpp | 3 +- externals/grill/pool/data.cpp | 568 +++++++------- externals/grill/pool/pool.cpp | 1228 +++++++++++++++--------------- externals/grill/pool/pool.dsp | 230 +++--- externals/grill/vst/src/EditorThread.cpp | 120 +-- externals/grill/vst/src/VstHost.cpp | 1082 +++++++++++++------------- externals/grill/xsample/xsample.cw | Bin 155147 -> 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 -#include -#include -#include - - -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):""); -} - -pooldata::~pooldata() -{ - LOG1("free pool %s",sym?flext_base::GetString(sym):""); -} - - -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,"",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 << "" << endl; - fl << "" << endl; - fl << "" << endl; - BL ret = pd->SvDirXML(fl,depth,tmp); - fl << "" << 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 +#include +#include +#include + + +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):""); +} + +pooldata::~pooldata() +{ + FLEXT_LOG1("free pool %s",sym?flext_base::GetString(sym):""); +} + + +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,"",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 << "" << endl; + fl << "" << endl; + fl << "" << endl; + BL ret = pd->SvDirXML(fl,depth,tmp); + fl << "" << 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 -#include -#include -#include - -#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<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 << "" << endl; - } - - for(I vi = 0; vi < vsize; ++vi) { - for(poolval *ix = vals[vi].v; ix; ix = ix->nxt) { - os << "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->SvDirXML(os,nd,AtomList(dir).Append(ix->dir)); - } - } - } - - if(dir.Count()) os << "" << 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 +#include +#include +#include + +#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<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 << "" << endl; + } + + for(I vi = 0; vi < vsize; ++vi) { + for(poolval *ix = vals[vi].v; ix; ix = ix->nxt) { + os << "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->SvDirXML(os,nd,AtomList(dir).Append(ix->dir)); + } + } + } + + if(dir.Count()) os << "" << 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;qprocessReplacing( _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 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;qprocessReplacing( _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