From c0a14908d98dad33c2732b084cc2580d78c5d98b Mon Sep 17 00:00:00 2001 From: Thomas Grill Date: Mon, 23 Aug 2004 02:42:16 +0000 Subject: "" svn path=/trunk/; revision=1970 --- externals/grill/vst/src/VstHost.cpp | 92 +++++++++++----- externals/grill/vst/src/VstHost.h | 17 +++ externals/grill/vst/src/main.cpp | 204 ++++++++++++++++++++++++++++-------- 3 files changed, 242 insertions(+), 71 deletions(-) (limited to 'externals/grill/vst/src') diff --git a/externals/grill/vst/src/VstHost.cpp b/externals/grill/vst/src/VstHost.cpp index 041acb76..bd686716 100644 --- a/externals/grill/vst/src/VstHost.cpp +++ b/externals/grill/vst/src/VstHost.cpp @@ -11,7 +11,7 @@ WARRANTIES, see the file, "license.txt," in this distribution. #include "VstHost.h" #include "AEffectx.h" -using namespace std; +#include static VstTimeInfo _timeInfo; @@ -21,7 +21,8 @@ typedef AEffect *(VSTCALLBACK *PVSTMAIN)(audioMasterCallback audioMaster); VSTPlugin::VSTPlugin(): h_dll(NULL),hwnd(NULL),_pEffect(NULL), posx(0),posy(0), - _midichannel(0),queue_size(0) + _midichannel(0),queue_size(0), + paramnamecnt(0) {} VSTPlugin::~VSTPlugin() @@ -62,39 +63,36 @@ int VSTPlugin::Instance(const char *dllname) ret = Dispatch( effIdentify); FLEXT_ASSERT(ret == 'NvEf'); - if (!Dispatch( effGetProductString, 0, 0, &_sProductName, 0.0f)) { + *_sProductName = 0; + Dispatch( effGetProductString, 0, 0, &_sProductName, 0.0f); + if(_sProductName) { // no product name given by plugin -> extract it from the filename - string str1(dllname); - string::size_type slpos = str1.rfind('\\'); - if(slpos == string::npos) { + std::string str1(dllname); + std::string::size_type slpos = str1.rfind('\\'); + if(slpos == std::string::npos) { slpos = str1.rfind('/'); - if(slpos == string::npos) + if(slpos == std::string::npos) slpos = 0; else ++slpos; } else ++slpos; - string str2 = str1.substr(slpos); + std::string str2 = str1.substr(slpos); int snip = str2.find('.'); - if( snip != string::npos ) + if( snip != std::string::npos ) str1 = str2.substr(0,snip); else str1 = str2; strcpy(_sProductName,str1.c_str()); } - if(!Dispatch( effGetVendorString, 0, 0, &_sVendorName, 0.0f)) - strcpy(_sVendorName, "Unknown vendor"); + *_sVendorName = 0; + Dispatch( effGetVendorString, 0, 0, &_sVendorName, 0.0f); _sDllName = dllname; -/* - Dispatch( effMainsChanged, 0, 1); - Dispatch( effSetSampleRate, 0, 0,NULL,44100.); - Dispatch( effSetBlockSize, 0, 64); -*/ return VSTINSTANCE_NO_ERROR; } @@ -140,19 +138,30 @@ void VSTPlugin::Free() // Called also in destruction void VSTPlugin::DspInit(float samplerate,int blocksize) { -// sample_rate = samplerate; - - Dispatch(effMainsChanged, 0, 1); + // sample rate and block size must _first_ be set Dispatch(effSetSampleRate, 0, 0,NULL,samplerate); Dispatch(effSetBlockSize, 0, blocksize); + // than signal that mains have changed! + Dispatch(effMainsChanged, 0, 1); +} + +static void striptrail(char *txt) +{ + // strip trailing whitespace + for(int i = strlen(txt)-1; i >= 0; --i) + // cast to unsigned char since isspace functions don't want characters like 0x80 = -128 + if(isspace(((unsigned char *)txt)[i])) txt[i] = 0; } void VSTPlugin::GetParamName(int numparam,char *name) const { - if(numparam < GetNumParams()) + if(numparam < GetNumParams()) { + name[0] = 0; Dispatch(effGetParamName,numparam,0,name,0.0f); + striptrail(name); + } else - strcpy(name,"Index out of Range"); + name[0] = 0; } bool VSTPlugin::SetParamFloat(int parameter,float value) @@ -169,14 +178,17 @@ void VSTPlugin::GetParamValue(int numparam,char *parval) const { if(Is()) { if(numparam < GetNumParams()) { -// char par_name[64]; - char par_display[64]; - char par_label[64]; - -// Dispatch(effGetParamName,parameter,0,par_name,0.0f); + // how many chars needed? + char par_display[64]; par_display[0] = 0; Dispatch(effGetParamDisplay,numparam,0,par_display,0.0f); - Dispatch(effGetParamLabel,numparam,0,par_label,0.0f); -// sprintf(psTxt,"%s:%s%s",par_name,par_display,par_label); +// if(par_display[7]) par_display[8] = 0; // set trailing zero + + // how many chars needed? + char par_label[64]; par_label[0] = 0; + Dispatch(effGetParamLabel,numparam,0,par_label,0.0f); + striptrail(par_label); +// if(par_label[7]) par_label[8] = 0; // set trailing zero + sprintf(parval,"%s%s",par_display,par_label); } else @@ -194,6 +206,26 @@ float VSTPlugin::GetParamValue(int numparam) const return -1.0; } +void VSTPlugin::ScanParams(int cnt) +{ + if(cnt < 0) cnt = GetNumParams(); + if(paramnamecnt >= cnt) return; + if(cnt >= GetNumParams()) cnt = GetNumParams(); + + char name[64]; + for(int i = paramnamecnt; i < cnt; ++i) { + GetParamName(i,name); + if(*name) paramnames[std::string(name)] = i; + } + paramnamecnt = cnt; +} + +int VSTPlugin::GetParamIx(const char *p) const +{ + NameMap::const_iterator it = paramnames.find(std::string(p)); + return it == paramnames.end()?-1:it->second; +} + void VSTPlugin::Edit(bool open) { if(Is()) { @@ -308,9 +340,11 @@ void VSTPlugin::AddControlChange(int control, int value) bool VSTPlugin::GetProgramName( int cat , int p, char *buf) const { + buf[0] = 0; int parameter = p; - if(parameter < GetNumPrograms()) { + if(parameter < GetNumPrograms() && cat < GetNumCategories()) { Dispatch(effGetProgramNameIndexed,parameter,cat,buf,0.0f); + striptrail(buf); return true; } else diff --git a/externals/grill/vst/src/VstHost.h b/externals/grill/vst/src/VstHost.h index bbbebe1f..00b5164f 100644 --- a/externals/grill/vst/src/VstHost.h +++ b/externals/grill/vst/src/VstHost.h @@ -72,6 +72,13 @@ public: void GetParamValue(int numparam,char *parval) const; float GetParamValue(int numparam) const; + // scan plugin names (can take a _long_ time!!) + void ScanParams(int i = -1); + // get number of scanned parameters + int ScannedParams() const { return paramnamecnt; } + // get index of named (scanned) parameter... -1 if not found + int GetParamIx(const char *p) const; + bool SetParamFloat(int parameter, float value); bool SetParamInt(int parameter, int value) { return SetParamFloat(parameter,value/65535.0f); } @@ -143,6 +150,16 @@ protected: char _sVendorName[64]; std::string _sDllName; // Contains dll name + struct NameCmp: + std::less + { + bool operator()(const std::string &a,const std::string &b) const { return a.compare(b) < 0; } + }; + + typedef std::map NameMap; + int paramnamecnt; + NameMap paramnames; + /* float *inputs[MAX_INOUTS]; float *outputs[MAX_INOUTS]; diff --git a/externals/grill/vst/src/main.cpp b/externals/grill/vst/src/main.cpp index 2467e1bd..13205a4d 100644 --- a/externals/grill/vst/src/main.cpp +++ b/externals/grill/vst/src/main.cpp @@ -17,10 +17,9 @@ WARRANTIES, see the file, "license.txt," in this distribution. #include #include -using namespace std; -#define VST_VERSION "0.1.0pre12" +#define VST_VERSION "0.1.0pre13" class vst: @@ -67,7 +66,18 @@ protected: V ms_program(I p); V mg_program(I &p) const { p = plug?plug->GetCurrentProgram():0; } + V mg_progname(int argc,const t_atom *argv) const; + V m_pname(I pnum); + V ms_paramnames(int cnt) { paramnames = cnt; if(plug) plug->ScanParams(cnt); } + + V ms_param(I pnum,F val); + V ms_params(int argc,const t_atom *argv); + V mg_param(I pnum); + V mg_params(int argc,const t_atom *argv); + V m_ptext(I pnum); + V m_ptexts(int argc,const t_atom *argv); + // V m_control(const S *ctrl_name,I ctrl_value); V m_pitchbend(I ctrl_value); V m_programchange(I ctrl_value); @@ -76,17 +86,13 @@ protected: V m_note(I note,I vel); inline V m_noteoff(I note) { m_note(note,0); } - V ms_param(I pnum,F val); - V mg_param(I pnum); - V m_pname(I pnum); - V m_ptext(I pnum); - private: V display_parameter(I param,BL showparams); VSTPlugin *plug; - string plugname; - BL echoparam,visible,bypass,mute; + std::string plugname; + bool echoparam,visible,bypass,mute; + int paramnames; I blsz; V (VSTPlugin::*vstfun)(R **insigs,R **outsigs,L n); @@ -119,10 +125,17 @@ private: FLEXT_CALLBACK_II(m_ctrlchange) FLEXT_CALLVAR_I(mg_program,ms_program) + FLEXT_CALLBACK_V(mg_progname) + + FLEXT_CALLBACK_I(m_pname) + FLEXT_ATTRGET_I(paramnames) + FLEXT_CALLSET_I(ms_paramnames) FLEXT_CALLBACK_2(ms_param,int,float) + FLEXT_CALLBACK_V(ms_params) FLEXT_CALLBACK_I(mg_param) - FLEXT_CALLBACK_I(m_pname) + FLEXT_CALLBACK_V(mg_params) FLEXT_CALLBACK_I(m_ptext) + FLEXT_CALLBACK_V(m_ptexts) FLEXT_CALLBACK_II(m_note) FLEXT_CALLBACK_I(m_noteoff) @@ -141,11 +154,15 @@ private: FLEXT_CALLGET_S(mg_plugdll) FLEXT_CALLGET_I(mg_plugversion) FLEXT_CALLGET_B(mg_issynth) + + static const t_symbol *sym_progname,*sym_pname,*sym_param,*sym_ptext; }; FLEXT_NEW_DSP_V("vst~",vst); +const t_symbol *vst::sym_progname,*vst::sym_pname,*vst::sym_param,*vst::sym_ptext; + V vst::Setup(t_classid c) { post(""); @@ -170,11 +187,16 @@ V vst::Setup(t_classid c) FLEXT_CADDMETHOD_(c,0,"progchg",m_programchange); FLEXT_CADDATTR_VAR(c,"program",mg_program,ms_program); + FLEXT_CADDMETHOD_(c,0,"getprogname",mg_progname); + FLEXT_CADDMETHOD_I(c,0,"getpname",m_pname); + FLEXT_CADDATTR_VAR(c,"pnames",paramnames,ms_paramnames); FLEXT_CADDMETHOD_2(c,0,"param",ms_param,int,float); + FLEXT_CADDMETHOD_2(c,0,"param",ms_params,t_symptr,float); FLEXT_CADDMETHOD_(c,0,"getparam",mg_param); - FLEXT_CADDMETHOD_I(c,0,"getpname",m_pname); - FLEXT_CADDMETHOD_I(c,0,"getptext",m_ptext); + FLEXT_CADDMETHOD_(c,0,"getparam",mg_params); + FLEXT_CADDMETHOD_(c,0,"getptext",m_ptext); + FLEXT_CADDMETHOD_(c,0,"getptext",m_ptexts); FLEXT_CADDATTR_VAR1(c,"echo",echoparam); FLEXT_CADDATTR_VAR(c,"x",mg_winx,ms_winx); @@ -191,6 +213,11 @@ V vst::Setup(t_classid c) FLEXT_CADDATTR_GET(c,"version",mg_plugversion); FLEXT_CADDATTR_GET(c,"synth",mg_issynth); + sym_progname = MakeSymbol("progname"); + sym_pname = MakeSymbol("pname"); + sym_param = MakeSymbol("param"); + sym_ptext = MakeSymbol("ptext"); + SetupEditor(); } @@ -199,7 +226,7 @@ vst::vst(I argc,const A *argv): plug(NULL),visible(false), blsz(0), vstfun(NULL),vstin(NULL),vstout(NULL),tmpin(NULL),tmpout(NULL), - echoparam(false),bypass(false),mute(false) + echoparam(false),bypass(false),mute(false),paramnames(0) { if(argc >= 2 && CanbeInt(argv[0]) && CanbeInt(argv[1])) { AddInSignal(GetAInt(argv[0])); @@ -234,6 +261,8 @@ V vst::InitPlug() InitPlugDSP(); InitBuf(); + + plug->ScanParams(paramnames); } V vst::InitPlugDSP() @@ -276,7 +305,7 @@ V vst::InitBuf() for(i = 0; i < outputs; ++i) vstout[i] = new R[Blocksize()]; } -static string findFilePath(const string &path,const string &dllname) +static std::string findFilePath(const std::string &path,const std::string &dllname) { _chdir( path.c_str() ); #if FLEXT_OS == FLEXT_OS_WIN @@ -308,7 +337,7 @@ static string findFilePath(const string &path,const string &dllname) } */ - return string(); + return std::string(); } @@ -322,6 +351,17 @@ BL vst::ms_plug(I argc,const A *argv) if(i > 0) plugname += ' '; GetAString(argv[i],buf,sizeof buf); strlwr(buf); + +#if FLEXT_SYS == FLEXT_SYS_PD + // strip char escapes (only in newer/devel PD version) + char *cs = buf,*cd = cs; + while(*cs) { + if(*cs != '\\') *(cd++) = *cs; + ++cs; + } + *cd = 0; +#endif + plugname += buf; } @@ -353,7 +393,7 @@ BL vst::ms_plug(I argc,const A *argv) // if dir is current working directory... name points to dir if(dir == name) strcpy(dir,"."); - string dllname(dir); + std::string dllname(dir); dllname += "\\"; dllname += name; @@ -362,9 +402,9 @@ BL vst::ms_plug(I argc,const A *argv) } if(!lf) { // try finding it on the VST path - C *vst_path = getenv ("VST_PATH"); + C *vst_path = getenv("VST_PATH"); - string dllname(plugname); + std::string dllname(plugname); if(dllname.find(".dll") == -1) dllname += ".dll"; if(vst_path) { @@ -373,12 +413,12 @@ BL vst::ms_plug(I argc,const A *argv) strcpy( tok_path , vst_path); char *tok = strtok( tok_path , ";" ); while( tok != NULL ) { - string abpath( tok ); + std::string abpath( tok ); if( abpath[abpath.length()-1] != '\\' ) abpath += "\\"; FLEXT_LOG1("trying VST_PATH %s",(const C *)abpath.c_str()); - string realpath = findFilePath( abpath , dllname ); + std::string realpath = findFilePath( abpath , dllname ); //post( "findFilePath( %s , %s ) = %s\n" , abpath , dllname , realpath ); if ( realpath.length() ) { realpath += plugname; @@ -444,13 +484,14 @@ V vst::m_signal(I n,R *const *insigs,R *const *outsigs) if(sigmatch) (plug->*vstfun)(const_cast(insigs),const_cast(outsigs),n); else { + const int cntin = CntInSig(),cntout = CntOutSig(); R **inv,**outv; - if(inputs <= CntInSig()) + if(inputs <= cntin) inv = const_cast(insigs); else { // more plug inputs than inlets I i; - for(i = 0; i < CntInSig(); ++i) tmpin[i] = const_cast(insigs[i]); + for(i = 0; i < cntin; ++i) tmpin[i] = const_cast(insigs[i]); // set dangling inputs to zero // according to mode... (e.g. set zero) @@ -459,24 +500,25 @@ V vst::m_signal(I n,R *const *insigs,R *const *outsigs) inv = tmpin; } - const BL more = outputs <= CntOutSig(); + const BL more = outputs <= cntout; if(more) // more outlets than plug outputs outv = const_cast(outsigs); else { I i; - for(i = 0; i < CntOutSig(); ++i) tmpout[i] = outsigs[i]; + for(i = 0; i < cntout; ++i) tmpout[i] = outsigs[i]; for(; i < outputs; ++i) tmpout[i] = vstout[i]; outv = tmpout; } + // call plugin DSP function (plug->*vstfun)(inv,outv,n); if(more) { // according to mode set dangling output vectors // currently simply clear them.... - for(int i = outputs; i < CntOutSig(); ++i) + for(int i = outputs; i < cntout; ++i) ZeroSamples(outsigs[i],n); } } @@ -531,6 +573,33 @@ V vst::ms_program(I p) if(plug && p >= 0) plug->SetCurrentProgram(p); } +void vst::mg_progname(int argc,const t_atom *argv) const +{ + if(plug) { + int cat,pnum; + if(argc == 1 && CanbeInt(argv[0])) { + cat = -1,pnum = GetAInt(argv[0]); + } + else if(argc == 2 && CanbeInt(argv[0]) && CanbeInt(argv[1])) { + cat = GetAInt(argv[0]),pnum = GetAInt(argv[1]); + } + else pnum = -1; + + if(pnum >= 0) { + char str[256]; + plug->GetProgramName(cat,pnum,str); + + A at[3]; + SetInt(at[0],cat); + SetInt(at[1],pnum); + SetString(at[2],str); + ToOutAnything(GetOutAttr(),sym_progname,3,at); + } + else + post("%s - Syntax: %s [category] program",thisName(),GetString(thisTag())); + } +} + V vst::m_ctrlchange(I control,I ctrl_value) { if(plug) plug->AddControlChange(control,ctrl_value ); @@ -639,7 +708,7 @@ V vst::display_parameter(I param,BL showparams) if(*name) { if (showparams) { -// plug->DescribeValue( j , display ); +// plug->DescribeValue( j , display ); plug->GetParamValue(j,display); val = plug->GetParamValue( j ); post ("parameter[#%d], \"%s\" value=%f (%s) ", j, name, val,display); @@ -651,6 +720,18 @@ V vst::display_parameter(I param,BL showparams) } } +V vst::m_pname(I pnum) +{ + if(!plug || pnum < 0 || pnum >= plug->GetNumParams()) return; + + char name[256]; // how many chars needed? + plug->GetParamName(pnum,name); + + A at[2]; + SetInt(at[0],pnum); + SetString(at[1],name); + ToOutAnything(GetOutAttr(),sym_pname,2,at); +} // set the value of a parameter V vst::ms_param(I pnum,F val) @@ -668,6 +749,25 @@ V vst::ms_param(I pnum,F val) FLEXT_ASSERT(false); } +void vst::ms_params(int argc,const t_atom *argv) +{ + if(plug) { + char str[255]; *str = 0; + if(argc && CanbeFloat(argv[argc-1])) + PrintList(argc-1,argv,str,sizeof str); + + if(*str) { + int ix = plug->GetParamIx(str); + if(ix >= 0) + ms_param(ix,GetAFloat(argv[argc-1])); + else + post("%s %s - Parameter not found",thisName(),GetString(thisTag()),str); + } + else + post("%s - Syntax: %s name value",thisName(),GetString(thisTag())); + } +} + V vst::mg_param(I pnum) { if(!plug || pnum < 0 || pnum >= plug->GetNumParams()) return; @@ -675,37 +775,57 @@ V vst::mg_param(I pnum) A at[2]; SetInt(at[0],pnum); SetFloat(at[1],plug->GetParamValue(pnum)); - ToOutAnything(GetOutAttr(),MakeSymbol("param"),2,at); + ToOutAnything(GetOutAttr(),sym_param,2,at); } -V vst::m_pname(I pnum) +V vst::mg_params(int argc,const t_atom *argv) { - if(!plug || pnum < 0 || pnum >= plug->GetNumParams()) return; - - C name[109]; /* the Steinberg(tm) way... */ - - memset(name,0,sizeof(name)); - plug->GetParamName(pnum,name); - - A at[2]; - SetInt(at[0],pnum); - SetString(at[1],name); - ToOutAnything(GetOutAttr(),MakeSymbol("pname"),2,at); + if(plug) { + char str[255]; + PrintList(argc,argv,str,sizeof str); + + if(*str) { + int ix = plug->GetParamIx(str); + if(ix >= 0) + mg_param(ix); + else + post("%s %s - Parameter not found",thisName(),GetString(thisTag()),str); + } + else + post("%s - Syntax: %s name value",thisName(),GetString(thisTag())); + } } V vst::m_ptext(I pnum) { if(!plug || pnum < 0 || pnum >= plug->GetNumParams()) return; - C display[164]; /* the Steinberg(tm) way... */ - + char display[256]; // how many chars needed? memset(display,0,sizeof(display)); plug->GetParamValue(pnum,display); A at[2]; SetInt(at[0],pnum); SetString(at[1],display); - ToOutAnything(GetOutAttr(),MakeSymbol("ptext"),2,at); + ToOutAnything(GetOutAttr(),sym_ptext,2,at); +} + +V vst::m_ptexts(int argc,const t_atom *argv) +{ + if(plug) { + char str[255]; + PrintList(argc,argv,str,sizeof str); + + if(*str) { + int ix = plug->GetParamIx(str); + if(ix >= 0) + m_ptext(ix); + else + post("%s %s - Parameter not found",thisName(),GetString(thisTag()),str); + } + else + post("%s - Syntax: %s name value",thisName(),GetString(thisTag())); + } } V vst::m_note(I note,I velocity) -- cgit v1.2.1