From fe9b0d819d5478fa8256a612f3ba7de44894baf5 Mon Sep 17 00:00:00 2001 From: Thomas Grill Date: Thu, 27 Feb 2003 04:41:15 +0000 Subject: "" svn path=/trunk/; revision=435 --- externals/grill/vst/license.txt | 18 +- externals/grill/vst/readme.txt | 112 +-- externals/grill/vst/src/main.cpp | 1426 +++++++++++++++++++------------------- externals/grill/vst/src/main.h | 2 +- 4 files changed, 787 insertions(+), 771 deletions(-) (limited to 'externals/grill/vst') diff --git a/externals/grill/vst/license.txt b/externals/grill/vst/license.txt index 8dcfb60d..11ae0af5 100644 --- a/externals/grill/vst/license.txt +++ b/externals/grill/vst/license.txt @@ -1,5 +1,5 @@ vst~ - VST plugin object for PD -based on the work of mark@junklight.com +based on the work of Jarno Seppänen and Mark Williamson Copyright (C) 2003 Thomas Grill This program is free software; you can redistribute it and/or @@ -26,6 +26,22 @@ in the file gpl.txt --------------------------------------------------------- This package uses the flext C++ layer - See its license text below: + +--- plugin~ by Jarno Seppänen -------------------------- + +This is a Pd [1] tilde object for hosting LADSPA [2] and VST [3] audio +plug-ins on Linux and Windows systems, respectively. The LADSPA +plug-in interface is supported completely on Linux, while the VST 1.0 +audio processing plug-in interface (without plug-in graphics) is +supported on Windows. + +This text corresponds to release 0.2 of plugin~ as of 4th April, 2001. +This release of plugin~ has been tested with Pd 0.32P1. + +plugin~ is distributed under the GNU General Public License. For more +information, please read the accompanying file "COPYING". + + --- vst by mark@junklight.com -------------------------- reference: http://iem.kug.ac.at/~jams/ diff --git a/externals/grill/vst/readme.txt b/externals/grill/vst/readme.txt index 876190d7..3918a7b2 100644 --- a/externals/grill/vst/readme.txt +++ b/externals/grill/vst/readme.txt @@ -1,56 +1,56 @@ -vst~ - VST plugin external for PD -based on the work of mark@junklight.com - -Copyright (c)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. - -Donations for further development of the package are highly appreciated. - ----------------------------------------------------------------------------- - -You will need the flext C++ layer for PD and Max/MSP externals to compile this. -see http://www.parasitaere-kapazitaeten.net/ext - ----------------------------------------------------------------------------- - - -BUILDING: -========= - - -pd - Windows: -------------- -o Microsoft Visual C++ 6: edit the project file "vst.dsp" & build - -pd - darwin (MacOSX): ---------------------- -o GCC: edit "config-pd-darwin.txt" & run "sh build-pd-darwin.sh" - -Max/MSP - MacOS9/X: -------------------- -o CodeWarrior: edit "vst.cw" and build - - ----------------------------------------------------------------------------- - -Version history: - -0.1.0: -- fixed crash when there's no "VST_PATH" environment string found -- included pd path into VST search path -- made thread of editor window low priority -- introduced A LOT of attributes to get info about the plugin -- make editor window closable by patch -- plugin can be changed with plug attribute - -0.0.0: -- version of mark@junklight.com - ---------------------------------------------------------------------------- - -features: -- allow various window styles and window moving & titling -- include necessary Steinberg license stuff - - +vst~ - VST plugin external for PD +based on the work of Jarno Seppänen and Mark Williamson + +Copyright (c)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. + +Donations for further development of the package are highly appreciated. + +---------------------------------------------------------------------------- + +You will need the flext C++ layer for PD and Max/MSP externals to compile this. +see http://www.parasitaere-kapazitaeten.net/ext + +---------------------------------------------------------------------------- + + +BUILDING: +========= + + +pd - Windows: +------------- +o Microsoft Visual C++ 6: edit the project file "vst.dsp" & build + +pd - darwin (MacOSX): +--------------------- +o GCC: edit "config-pd-darwin.txt" & run "sh build-pd-darwin.sh" + +Max/MSP - MacOS9/X: +------------------- +o CodeWarrior: edit "vst.cw" and build + + +---------------------------------------------------------------------------- + +Version history: + +0.1.0: +- fixed crash when there's no "VST_PATH" environment string found +- included pd path into VST search path +- made thread of editor window low priority +- introduced A LOT of attributes to get info about the plugin +- make editor window closable by patch +- plugin can be changed with plug attribute + +0.0.0: +- version of mark@junklight.com + +--------------------------------------------------------------------------- + +features: +- allow various window styles and window moving & titling +- include necessary Steinberg license stuff + + diff --git a/externals/grill/vst/src/main.cpp b/externals/grill/vst/src/main.cpp index 37e562a4..7854aa8f 100644 --- a/externals/grill/vst/src/main.cpp +++ b/externals/grill/vst/src/main.cpp @@ -1,713 +1,713 @@ -/* - -vst - VST plugin object for PD -based on the work of mark@junklight.com - -Copyright (c)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 "main.h" -#include "vst.h" - -#include "EditorThread.h" -#include "VstHost.h" - -#include -#include -#include - -#define VST_VERSION "0.1.0pre5" - -#if 0 -/* ----- MFC stuff ------------- */ - -BEGIN_MESSAGE_MAP(CVstApp, CWinApp) - //{{AFX_MSG_MAP(CVstApp) - // NOTE - the ClassWizard will add and remove mapping macros here. - // DO NOT EDIT what you see in these blocks of generated code! - //}}AFX_MSG_MAP -END_MESSAGE_MAP() - -CVstApp::CVstApp() {} - -CVstApp theApp; - -/* ----- MFC stuff ------------- */ -#endif - - -class vst: - public flext_dsp -{ - FLEXT_HEADER_S(vst,flext_dsp,Setup) - -public: - vst(I argc,const A *argv); - ~vst(); - -protected: - virtual V m_dsp(I n,t_signalvec const *insigs,t_signalvec const *outsigs); - virtual V m_signal(I n,R *const *insigs,R *const *outsigs); - - BL ms_plug(I argc,const A *argv); - BL ms_plug(const AtomList &args) { return ms_plug(args.Count(),args.Atoms()); } - V mg_plug(AtomList &sym) const { sym(1); SetString(sym[0],plugname); } - - V ms_edit(BL on); - V mg_edit(BL &ed) { ed = plug && plug->Edited(); } - V mg_editor(BL &ed) { ed = plug && plug->HasEditor(); } - V ms_vis(BL vis); - - V mg_winx(I &x) const { x = plug?plug->getX():0; } - V mg_winy(I &y) const { y = plug?plug->getY():0; } - V ms_winx(I x) { if(plug) plug->setX(x); } - V ms_winy(I y) { if(plug) plug->setY(y); } - - V mg_chnsin(I &c) const { c = plug?plug->getNumInputs():0; } - V mg_chnsout(I &c) const { c = plug?plug->getNumOutputs():0; } - V mg_params(I &p) const { p = plug?plug->GetNumParams():0; } - V mg_programs(I &p) const { p = plug?plug->NumPrograms():0; } - V mg_plugname(const S *&s) const { s = MakeSymbol(plug?plug->GetName():""); } - V mg_plugvendor(const S *&s) const { s = MakeSymbol(plug?plug->GetVendorName():""); } - V mg_plugdll(const S *&s) const { s = MakeSymbol(plug?plug->GetDllName():""); } - V mg_plugversion(I &v) const { v = plug?plug->GetVersion():0; } - V mg_issynth(BL &s) const { s = plug && plug->IsSynth(); } - - V m_print(I ac,const A *av); - - V ms_program(I p); - V mg_program(I &p) const { p = plug?plug->GetCurrentProgram():0; } - -// V m_control(const S *ctrl_name,I ctrl_value); - V m_pitchbend(I ctrl_value); - V m_programchange(I ctrl_value); - V m_aftertouch(I ctrl_value); - V m_ctrlchange(I control,I ctrl_value); - 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; - CString plugname; - BL echoparam,visible; - - I blsz; - V (VSTPlugin::*vstfun)(R **insigs,R **outsigs,L n); - BL sigmatch; - R **vstin,**vstout,**tmpin,**tmpout; - - V InitPlug(); - V ClearPlug(); - V InitBuf(); - V ClearBuf(); - static V Setup(t_classid); - - - FLEXT_CALLBACK_V(m_print) - - FLEXT_CALLVAR_V(mg_plug,ms_plug) - - FLEXT_CALLVAR_B(mg_edit,ms_edit) - FLEXT_CALLGET_B(mg_editor) - FLEXT_CALLSET_B(ms_vis) - FLEXT_ATTRGET_B(visible) - -// FLEXT_CALLBACK_2(m_control,t_symptr,int) - FLEXT_CALLBACK_I(m_pitchbend) - FLEXT_CALLBACK_I(m_aftertouch) - FLEXT_CALLBACK_I(m_programchange) - FLEXT_CALLBACK_II(m_ctrlchange) - - FLEXT_CALLVAR_I(mg_program,ms_program) - FLEXT_CALLBACK_2(ms_param,int,float) - FLEXT_CALLBACK_I(mg_param) - FLEXT_CALLBACK_I(m_pname) - FLEXT_CALLBACK_I(m_ptext) - - FLEXT_CALLBACK_II(m_note) - FLEXT_CALLBACK_I(m_noteoff) - - FLEXT_ATTRVAR_B(echoparam) - FLEXT_CALLVAR_I(mg_winx,ms_winx) - FLEXT_CALLVAR_I(mg_winy,ms_winy) - - FLEXT_CALLGET_I(mg_chnsin) - FLEXT_CALLGET_I(mg_chnsout) - FLEXT_CALLGET_I(mg_params) - FLEXT_CALLGET_I(mg_programs) - FLEXT_CALLGET_S(mg_plugname) - FLEXT_CALLGET_S(mg_plugvendor) - FLEXT_CALLGET_S(mg_plugdll) - FLEXT_CALLGET_I(mg_plugversion) - FLEXT_CALLGET_B(mg_issynth) -}; - -FLEXT_NEW_DSP_V("vst~",vst); - - -V vst::Setup(t_classid c) -{ -#if FLEXT_OS == FLEXT_OS_WIN - AFX_MANAGE_STATE(AfxGetStaticModuleState()); - AfxOleInit( ); -#endif - - post(""); - post("vst~ %s - VST plugin object, (C)2003 Thomas Grill",VST_VERSION); - post("based on the work of mark@junklight.com"); - post(""); - - FLEXT_CADDATTR_VAR(c,"plug",mg_plug,ms_plug); - FLEXT_CADDATTR_VAR(c,"edit",mg_edit,ms_edit); - FLEXT_CADDATTR_GET(c,"editor",mg_editor); - FLEXT_CADDATTR_VAR(c,"vis",visible,ms_vis); - FLEXT_CADDMETHOD_(c,0,"print",m_print); - - FLEXT_CADDMETHOD_II(c,0,"note",m_note); - FLEXT_CADDMETHOD_I(c,0,"noteoff",m_noteoff); -// FLEXT_CADDMETHOD_2(c,0,"control",m_control,t_symptr,int); - FLEXT_CADDMETHOD_(c,0,"pbend",m_pitchbend); - FLEXT_CADDMETHOD_(c,0,"atouch",m_aftertouch); - FLEXT_CADDMETHOD_II(c,0,"ctlchg",m_ctrlchange); - - FLEXT_CADDMETHOD_(c,0,"progchg",m_programchange); - FLEXT_CADDATTR_VAR(c,"program",mg_program,ms_program); - - FLEXT_CADDMETHOD_2(c,0,"param",ms_param,int,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_CADDATTR_VAR1(c,"echo",echoparam); - FLEXT_CADDATTR_VAR(c,"x",mg_winx,ms_winx); - FLEXT_CADDATTR_VAR(c,"y",mg_winy,ms_winy); - - FLEXT_CADDATTR_GET(c,"ins",mg_chnsin); - FLEXT_CADDATTR_GET(c,"outs",mg_chnsout); - FLEXT_CADDATTR_GET(c,"params",mg_params); - FLEXT_CADDATTR_GET(c,"programs",mg_programs); - FLEXT_CADDATTR_GET(c,"name",mg_plugname); - FLEXT_CADDATTR_GET(c,"vendor",mg_plugvendor); - FLEXT_CADDATTR_GET(c,"dll",mg_plugdll); - FLEXT_CADDATTR_GET(c,"version",mg_plugversion); - FLEXT_CADDATTR_GET(c,"synth",mg_issynth); -} - - -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) -{ - if(argc >= 2 && CanbeInt(argv[0]) && CanbeInt(argv[1])) { - AddInSignal(GetAInt(argv[0])); - AddOutSignal(GetAInt(argv[1])); - - if(!ms_plug(argc-2,argv+2)) InitProblem(); - } - else { - post("%s - syntax: vst~ inputs outputs [plug]",thisName()); - InitProblem(); - } -} - -vst::~vst() -{ - ClearPlug(); -} - -V vst::ClearPlug() -{ - if(plug) { - ClearBuf(); - delete plug; plug = NULL; - } -} - -V vst::InitPlug() -{ - FLEXT_ASSERT(plug); - - vstfun = plug->replace()?plug->processReplacing:plug->process; - sigmatch = plug->getNumInputs() == CntInSig() && plug->getNumOutputs() == CntOutSig(); - - InitBuf(); -} - -V vst::ClearBuf() -{ - if(!plug) return; - - if(vstin) { - for(I i = 0; i < plug->getNumInputs(); ++i) delete[] vstin[i]; - delete[] vstin; vstin = NULL; - delete[] tmpin; tmpin = NULL; - } - if(vstout) { - for(I i = 0; i < plug->getNumOutputs(); ++i) delete[] vstout[i]; - delete[] vstout; vstout = NULL; - delete[] tmpout; tmpout = NULL; - } -} - -V vst::InitBuf() -{ - FLEXT_ASSERT(!vstin && !tmpin && !vstout && !tmpout); - - I i; - - vstin = new R *[plug->getNumInputs()]; - tmpin = new R *[plug->getNumInputs()]; - for(i = 0; i < plug->getNumInputs(); ++i) vstin[i] = new R[Blocksize()]; - - vstout = new R *[plug->getNumOutputs()]; - tmpout = new R *[plug->getNumOutputs()]; - for(i = 0; i < plug->getNumOutputs(); ++i) vstout[i] = new R[Blocksize()]; -} - -static const C *findFilePath(const C *path,const C *dllname) -{ - CFileFind finder; - _chdir( path ); - - if(finder.FindFile( dllname )) - return path; - else { - finder.FindFile(); - while(finder.FindNextFile()) { - if(finder.IsDirectory()) { - if(!finder.IsDots()) { - CString *npath = new CString( finder.GetFilePath()); - const C *ret = findFilePath( *npath , dllname ); - if(ret) { - CString *retstr = new CString(ret); - return *retstr; - } - } - } - } - } - return NULL; -} - - -BL vst::ms_plug(I argc,const A *argv) -{ - ClearPlug(); - - plugname.Empty(); - C buf[255]; - for(I i = 0; i < argc; i++) { - if(i > 0) plugname += ' '; - GetAString(argv[i],buf,sizeof buf); - plugname += buf; - } - plugname.MakeLower(); - if(!plugname.GetLength()) return false; - - plug = new VSTPlugin; - - // now try to load plugin - - // to help deal with spaces we assume ALL of the args make - // up the filename - bool lf = false; - int loaderr = VSTINSTANCE_NO_ERROR; - - // try loading the dll from the raw filename - if ((loaderr = plug->Instance(plugname)) == VSTINSTANCE_NO_ERROR) { - FLEXT_LOG("raw filename loaded fine"); - lf = true; - } - - if(!lf) { // try finding it on the PD path - C *name,dir[1024]; - I fd = open_via_path("",plugname,".dll",dir,&name,sizeof(dir)-1,0); - if(fd > 0) close(fd); - else name = NULL; - - if(name) { - FLEXT_LOG("found VST dll on the PD path"); - // if dir is current working directory... name points to dir - if(dir == name) strcpy(dir,"."); - - CString dllname(dir); - dllname += "\\"; - dllname += name; - - lf = (loaderr = plug->Instance(dllname)) == VSTINSTANCE_NO_ERROR; - } - } - - if(!lf) { // try finding it on the VST path - C *vst_path = getenv ("VST_PATH"); - - CString dllname(plugname); - if(dllname.Find(".dll") == -1) dllname += ".dll"; - - if(vst_path) { - FLEXT_LOG("found VST_PATH env variable"); - char* tok_path = new C[strlen( vst_path)+1]; - strcpy( tok_path , vst_path); - char *tok = strtok( tok_path , ";" ); - while( tok != NULL ) { - CString abpath( tok ); - if( abpath.Right( 1 ) != _T("\\") ) abpath += "\\"; - - FLEXT_LOG1("trying VST_PATH %s",(const C *)abpath); - - const char * realpath = findFilePath( abpath , dllname ); - //post( "findFilePath( %s , %s ) = %s\n" , abpath , dllname , realpath ); - if ( realpath != NULL ) { - CString rpath( realpath ); - rpath += plugname; - FLEXT_LOG1("trying %s",(const C *)rpath); - if((loaderr = plug->Instance( rpath )) == VSTINSTANCE_NO_ERROR ) { - FLEXT_LOG("plugin loaded via VST_PATH"); - lf = true; - break; - } - } - - tok = strtok( NULL , ";" ); - if(!tok) post("%s - couldn't find plugin",thisName()); - } - - delete[] tok_path; - } - } - - if(!lf) { // failed - don't make any ins or outs - post("%s - unable to load plugin '%s', load error %i",thisName(),plugname,loaderr); - ClearPlug(); - } - - // re-init dsp stuff - if(plug) InitPlug(); - - return lf; -} - -V vst::m_dsp(I n,t_signalvec const *,t_signalvec const *) -{ - if(plug) { - plug->Init(Samplerate(),(F)Blocksize()); - FLEXT_ASSERT(vstfun); - - if(blsz != Blocksize()) { - blsz = Blocksize(); - ClearBuf(); - InitBuf(); - } - } -} - -V vst::m_signal(I n,R *const *insigs,R *const *outsigs) -{ - if(plug) { - if(sigmatch) - (plug->*vstfun)(const_cast(insigs),const_cast(outsigs),n); - else { - R **inv,**outv; - - if(plug->getNumInputs() <= CntInSig()) - inv = const_cast(insigs); - else { // more plug inputs than inlets - I i; - for(i = 0; i < CntInSig(); ++i) tmpin[i] = const_cast(insigs[i]); - - // set dangling inputs to zero - // according to mode... (e.g. set zero) - for(; i < plug->getNumInputs(); ++i) ZeroSamples(tmpin[i] = vstin[i],n); - - inv = tmpin; - } - - const BL more = plug->getNumOutputs() <= CntOutSig(); - 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 < plug->getNumOutputs(); ++i) tmpout[i] = vstout[i]; - - outv = tmpout; - } - - (plug->*vstfun)(inv,outv,n); - - if(more) { - // according to mode set dangling output vectors - } - } - } - else - flext_dsp::m_signal(n,insigs,outsigs); -} - - -#if 0 - -V vst::m_control(const S *ctrl_name,I ctrl_value) -{ - if(!plug) return; - - I parm_num = 0; - - if (!*GetString(ctrl_name) || !strlen(GetString(ctrl_name))) { - error ("plugin~: control messages must have a name and a value"); - return; - } - //parm_num = vst_tilde_get_parm_number (x, ctrl_name->s_name); - //if (parm_num) - //{ - //vst_tilde_set_control_input_by_index (x, parm_num - 1, ctrl_value); - //} - //else - //{ - //vst_tilde_set_control_input_by_name (x, ctrl_name->s_name, ctrl_value); - //} -} - -#endif - -V vst::m_pitchbend(I ctrl_value) -{ - if(plug) plug->AddPitchBend(ctrl_value ); -} - -V vst::m_aftertouch(I ctrl_value) -{ - if(plug) plug->AddAftertouch(ctrl_value ); -} - -V vst::m_programchange(I ctrl_value) -{ - if(plug) plug->AddProgramChange(ctrl_value ); -} - -V vst::ms_program(I p) -{ - if(plug && p >= 0) plug->SetCurrentProgram(p); -} - -V vst::m_ctrlchange(I control,I ctrl_value) -{ - if(plug) plug->AddControlChange(control,ctrl_value ); -} - - - /** - * display the parameters names and values and some other bits and pieces that - * may be of use - */ - -V vst::m_print(I ac,const A *av) -{ - if(!plug) return; - - int i; - bool params = false; - bool header = true; - bool programs = false; - bool parameters = true; - int specific = -1; - if( ac > 0 ) { - for( i = 0 ; i < ac ; i++) { - if(IsString(av[i])) { - const C *buf = GetString(av[i]); - if ( strcmp( buf , "-params" ) == 0 ) { - params = true; - } - else if ( strcmp( buf , "-noheader" ) == 0 ) { - header = false; - } - else if ( strcmp( buf , "-programs" ) == 0 ) { - programs = true; - parameters = false; - } - else if ( strcmp( buf , "-parameters" ) == 0 ) { - parameters = false; - } - else if ( strcmp( buf , "-help" ) == 0 ) { - post("print options:"); - post("-help \t\tprint this"); - post("-programs \tshow the programs"); - post("-parameters \tshow the parameters"); - post("-params \tshow the parameter display values"); - post("-noheader \tdo not display the header"); - return; - } - } - else if(CanbeInt(av[i])) { - int p = GetAInt(av[i]); - if (( p > 0 ) && ( p <= plug->GetNumParams())) { - specific = p - 1; - } - } - } - } - - if ( header ) { - post("VST~ plugin: %s " , plug->GetName() ); - post("made by: %s " , plug->GetVendorName() ); - post("parameterss %d\naudio: %d in(s)/%d out(s) \nLoaded from library \"%s\".\n", - plug->GetNumParams(), - CntInSig(), - CntOutSig(), - plug->GetDllName()); - - post("Flags"); - if ( plug->_pEffect->flags & effFlagsHasEditor ) { - post("Has editor"); - } - if ( plug->_pEffect->flags & effFlagsCanReplacing ) { - post("Can do replacing"); - } - } - - if ( parameters ) { - if ( specific == -1) { - for (i = 0; i < plug->GetNumParams(); i++) - display_parameter( i , params ); - } - else - display_parameter( specific , params); - } - - if( programs ) { - for( int j = 0; j < plug->GetNumCategories() ; j++ ) { - for( i = 0 ; i < plug->GetNumParams() ; i++ ) { - char buf[64]; - plug->GetProgramName( j , i , buf ); - post("Program %d: %s ", i , buf ); - } - } - } -} - - -//! display an editor -V vst::ms_edit(BL on) -{ -#if FLEXT_OS == FLEXT_OS_WIN - AFX_MANAGE_STATE(AfxGetStaticModuleState()); -#endif - - if(plug) plug->edit(on); -} - -V vst::ms_vis(BL vis) -{ -#if FLEXT_OS == FLEXT_OS_WIN - AFX_MANAGE_STATE(AfxGetStaticModuleState()); -#endif - - if(plug) plug->visible(vis); -} - - -V vst::display_parameter(I param,BL showparams) -{ - int j = param; - /* the Steinberg(tm) way... */ - char name[109]; - char display[164]; - float val; - -// if(j == 0) post ("Control input/output(s):"); - - memset (name, 0, sizeof(name)); - memset( display, 0 ,sizeof(display)); - plug->GetParamName( j , name ); - - if(*name) { - if (showparams) { - plug->DescribeValue( j , display ); - val = plug->GetParamValue( j ); - post ("parameter[#%d], \"%s\" value=%f (%s) ", j, name, val,display); - } - else { - val = plug->GetParamValue( j ); - post ("parameter[#%d], \"%s\" value=%f ", j, name, val); - } - } -} - - -// set the value of a parameter -V vst::ms_param(I pnum,F val) -{ - if(!plug || pnum < 0 || pnum >= plug->GetNumParams()) return; - - F xval = plug->GetParamValue( pnum ); -// if(xval <= 1.0f) // What's that???? - if(true) - { - plug->SetParameter( pnum, val ); - if(echoparam) display_parameter(pnum , true ); - } - else - FLEXT_ASSERT(false); -} - -V vst::mg_param(I pnum) -{ - if(!plug || pnum < 0 || pnum >= plug->GetNumParams()) return; - - A at[2]; - SetInt(at[0],pnum); - SetFloat(at[1],plug->GetParamValue(pnum)); - ToOutAnything(GetOutAttr(),MakeSymbol("param"),2,at); -} - -V vst::m_pname(I pnum) -{ - 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); -} - -V vst::m_ptext(I pnum) -{ - if(!plug || pnum < 0 || pnum >= plug->GetNumParams()) return; - - C display[164]; /* the Steinberg(tm) way... */ - - memset(display,0,sizeof(display)); - plug->DescribeValue(pnum,display); - - A at[2]; - SetInt(at[0],pnum); - SetString(at[1],display); - ToOutAnything(GetOutAttr(),MakeSymbol("ptext"),2,at); -} - -V vst::m_note(I note,I velocity) -{ - if(!plug) return; - - if(velocity > 0) - plug->AddNoteOn(note,velocity); - else - plug->AddNoteOff(note); -} +/* + +vst - VST plugin object for PD +based on the work of Jarno Seppänen and Mark Williamson + +Copyright (c)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 "main.h" +#include "vst.h" + +#include "EditorThread.h" +#include "VstHost.h" + +#include +#include +#include + +#define VST_VERSION "0.1.0pre5" + +#if 0 +/* ----- MFC stuff ------------- */ + +BEGIN_MESSAGE_MAP(CVstApp, CWinApp) + //{{AFX_MSG_MAP(CVstApp) + // NOTE - the ClassWizard will add and remove mapping macros here. + // DO NOT EDIT what you see in these blocks of generated code! + //}}AFX_MSG_MAP +END_MESSAGE_MAP() + +CVstApp::CVstApp() {} + +CVstApp theApp; + +/* ----- MFC stuff ------------- */ +#endif + + +class vst: + public flext_dsp +{ + FLEXT_HEADER_S(vst,flext_dsp,Setup) + +public: + vst(I argc,const A *argv); + ~vst(); + +protected: + virtual V m_dsp(I n,t_signalvec const *insigs,t_signalvec const *outsigs); + virtual V m_signal(I n,R *const *insigs,R *const *outsigs); + + BL ms_plug(I argc,const A *argv); + BL ms_plug(const AtomList &args) { return ms_plug(args.Count(),args.Atoms()); } + V mg_plug(AtomList &sym) const { sym(1); SetString(sym[0],plugname); } + + V ms_edit(BL on); + V mg_edit(BL &ed) { ed = plug && plug->Edited(); } + V mg_editor(BL &ed) { ed = plug && plug->HasEditor(); } + V ms_vis(BL vis); + + V mg_winx(I &x) const { x = plug?plug->getX():0; } + V mg_winy(I &y) const { y = plug?plug->getY():0; } + V ms_winx(I x) { if(plug) plug->setX(x); } + V ms_winy(I y) { if(plug) plug->setY(y); } + + V mg_chnsin(I &c) const { c = plug?plug->getNumInputs():0; } + V mg_chnsout(I &c) const { c = plug?plug->getNumOutputs():0; } + V mg_params(I &p) const { p = plug?plug->GetNumParams():0; } + V mg_programs(I &p) const { p = plug?plug->NumPrograms():0; } + V mg_plugname(const S *&s) const { s = MakeSymbol(plug?plug->GetName():""); } + V mg_plugvendor(const S *&s) const { s = MakeSymbol(plug?plug->GetVendorName():""); } + V mg_plugdll(const S *&s) const { s = MakeSymbol(plug?plug->GetDllName():""); } + V mg_plugversion(I &v) const { v = plug?plug->GetVersion():0; } + V mg_issynth(BL &s) const { s = plug && plug->IsSynth(); } + + V m_print(I ac,const A *av); + + V ms_program(I p); + V mg_program(I &p) const { p = plug?plug->GetCurrentProgram():0; } + +// V m_control(const S *ctrl_name,I ctrl_value); + V m_pitchbend(I ctrl_value); + V m_programchange(I ctrl_value); + V m_aftertouch(I ctrl_value); + V m_ctrlchange(I control,I ctrl_value); + 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; + CString plugname; + BL echoparam,visible; + + I blsz; + V (VSTPlugin::*vstfun)(R **insigs,R **outsigs,L n); + BL sigmatch; + R **vstin,**vstout,**tmpin,**tmpout; + + V InitPlug(); + V ClearPlug(); + V InitBuf(); + V ClearBuf(); + static V Setup(t_classid); + + + FLEXT_CALLBACK_V(m_print) + + FLEXT_CALLVAR_V(mg_plug,ms_plug) + + FLEXT_CALLVAR_B(mg_edit,ms_edit) + FLEXT_CALLGET_B(mg_editor) + FLEXT_CALLSET_B(ms_vis) + FLEXT_ATTRGET_B(visible) + +// FLEXT_CALLBACK_2(m_control,t_symptr,int) + FLEXT_CALLBACK_I(m_pitchbend) + FLEXT_CALLBACK_I(m_aftertouch) + FLEXT_CALLBACK_I(m_programchange) + FLEXT_CALLBACK_II(m_ctrlchange) + + FLEXT_CALLVAR_I(mg_program,ms_program) + FLEXT_CALLBACK_2(ms_param,int,float) + FLEXT_CALLBACK_I(mg_param) + FLEXT_CALLBACK_I(m_pname) + FLEXT_CALLBACK_I(m_ptext) + + FLEXT_CALLBACK_II(m_note) + FLEXT_CALLBACK_I(m_noteoff) + + FLEXT_ATTRVAR_B(echoparam) + FLEXT_CALLVAR_I(mg_winx,ms_winx) + FLEXT_CALLVAR_I(mg_winy,ms_winy) + + FLEXT_CALLGET_I(mg_chnsin) + FLEXT_CALLGET_I(mg_chnsout) + FLEXT_CALLGET_I(mg_params) + FLEXT_CALLGET_I(mg_programs) + FLEXT_CALLGET_S(mg_plugname) + FLEXT_CALLGET_S(mg_plugvendor) + FLEXT_CALLGET_S(mg_plugdll) + FLEXT_CALLGET_I(mg_plugversion) + FLEXT_CALLGET_B(mg_issynth) +}; + +FLEXT_NEW_DSP_V("vst~",vst); + + +V vst::Setup(t_classid c) +{ +#if FLEXT_OS == FLEXT_OS_WIN + AFX_MANAGE_STATE(AfxGetStaticModuleState()); + AfxOleInit( ); +#endif + + post(""); + post("vst~ %s - VST plugin object, (C)2003 Thomas Grill",VST_VERSION); + post("based on the work of Jarno Seppänen and Mark Williamson"); + post(""); + + FLEXT_CADDATTR_VAR(c,"plug",mg_plug,ms_plug); + FLEXT_CADDATTR_VAR(c,"edit",mg_edit,ms_edit); + FLEXT_CADDATTR_GET(c,"editor",mg_editor); + FLEXT_CADDATTR_VAR(c,"vis",visible,ms_vis); + FLEXT_CADDMETHOD_(c,0,"print",m_print); + + FLEXT_CADDMETHOD_II(c,0,"note",m_note); + FLEXT_CADDMETHOD_I(c,0,"noteoff",m_noteoff); +// FLEXT_CADDMETHOD_2(c,0,"control",m_control,t_symptr,int); + FLEXT_CADDMETHOD_(c,0,"pbend",m_pitchbend); + FLEXT_CADDMETHOD_(c,0,"atouch",m_aftertouch); + FLEXT_CADDMETHOD_II(c,0,"ctlchg",m_ctrlchange); + + FLEXT_CADDMETHOD_(c,0,"progchg",m_programchange); + FLEXT_CADDATTR_VAR(c,"program",mg_program,ms_program); + + FLEXT_CADDMETHOD_2(c,0,"param",ms_param,int,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_CADDATTR_VAR1(c,"echo",echoparam); + FLEXT_CADDATTR_VAR(c,"x",mg_winx,ms_winx); + FLEXT_CADDATTR_VAR(c,"y",mg_winy,ms_winy); + + FLEXT_CADDATTR_GET(c,"ins",mg_chnsin); + FLEXT_CADDATTR_GET(c,"outs",mg_chnsout); + FLEXT_CADDATTR_GET(c,"params",mg_params); + FLEXT_CADDATTR_GET(c,"programs",mg_programs); + FLEXT_CADDATTR_GET(c,"name",mg_plugname); + FLEXT_CADDATTR_GET(c,"vendor",mg_plugvendor); + FLEXT_CADDATTR_GET(c,"dll",mg_plugdll); + FLEXT_CADDATTR_GET(c,"version",mg_plugversion); + FLEXT_CADDATTR_GET(c,"synth",mg_issynth); +} + + +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) +{ + if(argc >= 2 && CanbeInt(argv[0]) && CanbeInt(argv[1])) { + AddInSignal(GetAInt(argv[0])); + AddOutSignal(GetAInt(argv[1])); + + if(!ms_plug(argc-2,argv+2)) InitProblem(); + } + else { + post("%s - syntax: vst~ inputs outputs [plug]",thisName()); + InitProblem(); + } +} + +vst::~vst() +{ + ClearPlug(); +} + +V vst::ClearPlug() +{ + if(plug) { + ClearBuf(); + delete plug; plug = NULL; + } +} + +V vst::InitPlug() +{ + FLEXT_ASSERT(plug); + + vstfun = plug->replace()?plug->processReplacing:plug->process; + sigmatch = plug->getNumInputs() == CntInSig() && plug->getNumOutputs() == CntOutSig(); + + InitBuf(); +} + +V vst::ClearBuf() +{ + if(!plug) return; + + if(vstin) { + for(I i = 0; i < plug->getNumInputs(); ++i) delete[] vstin[i]; + delete[] vstin; vstin = NULL; + delete[] tmpin; tmpin = NULL; + } + if(vstout) { + for(I i = 0; i < plug->getNumOutputs(); ++i) delete[] vstout[i]; + delete[] vstout; vstout = NULL; + delete[] tmpout; tmpout = NULL; + } +} + +V vst::InitBuf() +{ + FLEXT_ASSERT(!vstin && !tmpin && !vstout && !tmpout); + + I i; + + vstin = new R *[plug->getNumInputs()]; + tmpin = new R *[plug->getNumInputs()]; + for(i = 0; i < plug->getNumInputs(); ++i) vstin[i] = new R[Blocksize()]; + + vstout = new R *[plug->getNumOutputs()]; + tmpout = new R *[plug->getNumOutputs()]; + for(i = 0; i < plug->getNumOutputs(); ++i) vstout[i] = new R[Blocksize()]; +} + +static const C *findFilePath(const C *path,const C *dllname) +{ + CFileFind finder; + _chdir( path ); + + if(finder.FindFile( dllname )) + return path; + else { + finder.FindFile(); + while(finder.FindNextFile()) { + if(finder.IsDirectory()) { + if(!finder.IsDots()) { + CString *npath = new CString( finder.GetFilePath()); + const C *ret = findFilePath( *npath , dllname ); + if(ret) { + CString *retstr = new CString(ret); + return *retstr; + } + } + } + } + } + return NULL; +} + + +BL vst::ms_plug(I argc,const A *argv) +{ + ClearPlug(); + + plugname.Empty(); + C buf[255]; + for(I i = 0; i < argc; i++) { + if(i > 0) plugname += ' '; + GetAString(argv[i],buf,sizeof buf); + plugname += buf; + } + plugname.MakeLower(); + if(!plugname.GetLength()) return false; + + plug = new VSTPlugin; + + // now try to load plugin + + // to help deal with spaces we assume ALL of the args make + // up the filename + bool lf = false; + int loaderr = VSTINSTANCE_NO_ERROR; + + // try loading the dll from the raw filename + if ((loaderr = plug->Instance(plugname)) == VSTINSTANCE_NO_ERROR) { + FLEXT_LOG("raw filename loaded fine"); + lf = true; + } + + if(!lf) { // try finding it on the PD path + C *name,dir[1024]; + I fd = open_via_path("",plugname,".dll",dir,&name,sizeof(dir)-1,0); + if(fd > 0) close(fd); + else name = NULL; + + if(name) { + FLEXT_LOG("found VST dll on the PD path"); + // if dir is current working directory... name points to dir + if(dir == name) strcpy(dir,"."); + + CString dllname(dir); + dllname += "\\"; + dllname += name; + + lf = (loaderr = plug->Instance(dllname)) == VSTINSTANCE_NO_ERROR; + } + } + + if(!lf) { // try finding it on the VST path + C *vst_path = getenv ("VST_PATH"); + + CString dllname(plugname); + if(dllname.Find(".dll") == -1) dllname += ".dll"; + + if(vst_path) { + FLEXT_LOG("found VST_PATH env variable"); + char* tok_path = new C[strlen( vst_path)+1]; + strcpy( tok_path , vst_path); + char *tok = strtok( tok_path , ";" ); + while( tok != NULL ) { + CString abpath( tok ); + if( abpath.Right( 1 ) != _T("\\") ) abpath += "\\"; + + FLEXT_LOG1("trying VST_PATH %s",(const C *)abpath); + + const char * realpath = findFilePath( abpath , dllname ); + //post( "findFilePath( %s , %s ) = %s\n" , abpath , dllname , realpath ); + if ( realpath != NULL ) { + CString rpath( realpath ); + rpath += plugname; + FLEXT_LOG1("trying %s",(const C *)rpath); + if((loaderr = plug->Instance( rpath )) == VSTINSTANCE_NO_ERROR ) { + FLEXT_LOG("plugin loaded via VST_PATH"); + lf = true; + break; + } + } + + tok = strtok( NULL , ";" ); + if(!tok) post("%s - couldn't find plugin",thisName()); + } + + delete[] tok_path; + } + } + + if(!lf) { // failed - don't make any ins or outs + post("%s - unable to load plugin '%s', load error %i",thisName(),plugname,loaderr); + ClearPlug(); + } + + // re-init dsp stuff + if(plug) InitPlug(); + + return lf; +} + +V vst::m_dsp(I n,t_signalvec const *,t_signalvec const *) +{ + if(plug) { + plug->Init(Samplerate(),(F)Blocksize()); + FLEXT_ASSERT(vstfun); + + if(blsz != Blocksize()) { + blsz = Blocksize(); + ClearBuf(); + InitBuf(); + } + } +} + +V vst::m_signal(I n,R *const *insigs,R *const *outsigs) +{ + if(plug) { + if(sigmatch) + (plug->*vstfun)(const_cast(insigs),const_cast(outsigs),n); + else { + R **inv,**outv; + + if(plug->getNumInputs() <= CntInSig()) + inv = const_cast(insigs); + else { // more plug inputs than inlets + I i; + for(i = 0; i < CntInSig(); ++i) tmpin[i] = const_cast(insigs[i]); + + // set dangling inputs to zero + // according to mode... (e.g. set zero) + for(; i < plug->getNumInputs(); ++i) ZeroSamples(tmpin[i] = vstin[i],n); + + inv = tmpin; + } + + const BL more = plug->getNumOutputs() <= CntOutSig(); + 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 < plug->getNumOutputs(); ++i) tmpout[i] = vstout[i]; + + outv = tmpout; + } + + (plug->*vstfun)(inv,outv,n); + + if(more) { + // according to mode set dangling output vectors + } + } + } + else + flext_dsp::m_signal(n,insigs,outsigs); +} + + +#if 0 + +V vst::m_control(const S *ctrl_name,I ctrl_value) +{ + if(!plug) return; + + I parm_num = 0; + + if (!*GetString(ctrl_name) || !strlen(GetString(ctrl_name))) { + error ("plugin~: control messages must have a name and a value"); + return; + } + //parm_num = vst_tilde_get_parm_number (x, ctrl_name->s_name); + //if (parm_num) + //{ + //vst_tilde_set_control_input_by_index (x, parm_num - 1, ctrl_value); + //} + //else + //{ + //vst_tilde_set_control_input_by_name (x, ctrl_name->s_name, ctrl_value); + //} +} + +#endif + +V vst::m_pitchbend(I ctrl_value) +{ + if(plug) plug->AddPitchBend(ctrl_value ); +} + +V vst::m_aftertouch(I ctrl_value) +{ + if(plug) plug->AddAftertouch(ctrl_value ); +} + +V vst::m_programchange(I ctrl_value) +{ + if(plug) plug->AddProgramChange(ctrl_value ); +} + +V vst::ms_program(I p) +{ + if(plug && p >= 0) plug->SetCurrentProgram(p); +} + +V vst::m_ctrlchange(I control,I ctrl_value) +{ + if(plug) plug->AddControlChange(control,ctrl_value ); +} + + + /** + * display the parameters names and values and some other bits and pieces that + * may be of use + */ + +V vst::m_print(I ac,const A *av) +{ + if(!plug) return; + + int i; + bool params = false; + bool header = true; + bool programs = false; + bool parameters = true; + int specific = -1; + if( ac > 0 ) { + for( i = 0 ; i < ac ; i++) { + if(IsString(av[i])) { + const C *buf = GetString(av[i]); + if ( strcmp( buf , "-params" ) == 0 ) { + params = true; + } + else if ( strcmp( buf , "-noheader" ) == 0 ) { + header = false; + } + else if ( strcmp( buf , "-programs" ) == 0 ) { + programs = true; + parameters = false; + } + else if ( strcmp( buf , "-parameters" ) == 0 ) { + parameters = false; + } + else if ( strcmp( buf , "-help" ) == 0 ) { + post("print options:"); + post("-help \t\tprint this"); + post("-programs \tshow the programs"); + post("-parameters \tshow the parameters"); + post("-params \tshow the parameter display values"); + post("-noheader \tdo not display the header"); + return; + } + } + else if(CanbeInt(av[i])) { + int p = GetAInt(av[i]); + if (( p > 0 ) && ( p <= plug->GetNumParams())) { + specific = p - 1; + } + } + } + } + + if ( header ) { + post("VST~ plugin: %s " , plug->GetName() ); + post("made by: %s " , plug->GetVendorName() ); + post("parameterss %d\naudio: %d in(s)/%d out(s) \nLoaded from library \"%s\".\n", + plug->GetNumParams(), + CntInSig(), + CntOutSig(), + plug->GetDllName()); + + post("Flags"); + if ( plug->_pEffect->flags & effFlagsHasEditor ) { + post("Has editor"); + } + if ( plug->_pEffect->flags & effFlagsCanReplacing ) { + post("Can do replacing"); + } + } + + if ( parameters ) { + if ( specific == -1) { + for (i = 0; i < plug->GetNumParams(); i++) + display_parameter( i , params ); + } + else + display_parameter( specific , params); + } + + if( programs ) { + for( int j = 0; j < plug->GetNumCategories() ; j++ ) { + for( i = 0 ; i < plug->GetNumParams() ; i++ ) { + char buf[64]; + plug->GetProgramName( j , i , buf ); + post("Program %d: %s ", i , buf ); + } + } + } +} + + +//! display an editor +V vst::ms_edit(BL on) +{ +#if FLEXT_OS == FLEXT_OS_WIN + AFX_MANAGE_STATE(AfxGetStaticModuleState()); +#endif + + if(plug) plug->edit(on); +} + +V vst::ms_vis(BL vis) +{ +#if FLEXT_OS == FLEXT_OS_WIN + AFX_MANAGE_STATE(AfxGetStaticModuleState()); +#endif + + if(plug) plug->visible(vis); +} + + +V vst::display_parameter(I param,BL showparams) +{ + int j = param; + /* the Steinberg(tm) way... */ + char name[109]; + char display[164]; + float val; + +// if(j == 0) post ("Control input/output(s):"); + + memset (name, 0, sizeof(name)); + memset( display, 0 ,sizeof(display)); + plug->GetParamName( j , name ); + + if(*name) { + if (showparams) { + plug->DescribeValue( j , display ); + val = plug->GetParamValue( j ); + post ("parameter[#%d], \"%s\" value=%f (%s) ", j, name, val,display); + } + else { + val = plug->GetParamValue( j ); + post ("parameter[#%d], \"%s\" value=%f ", j, name, val); + } + } +} + + +// set the value of a parameter +V vst::ms_param(I pnum,F val) +{ + if(!plug || pnum < 0 || pnum >= plug->GetNumParams()) return; + + F xval = plug->GetParamValue( pnum ); +// if(xval <= 1.0f) // What's that???? + if(true) + { + plug->SetParameter( pnum, val ); + if(echoparam) display_parameter(pnum , true ); + } + else + FLEXT_ASSERT(false); +} + +V vst::mg_param(I pnum) +{ + if(!plug || pnum < 0 || pnum >= plug->GetNumParams()) return; + + A at[2]; + SetInt(at[0],pnum); + SetFloat(at[1],plug->GetParamValue(pnum)); + ToOutAnything(GetOutAttr(),MakeSymbol("param"),2,at); +} + +V vst::m_pname(I pnum) +{ + 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); +} + +V vst::m_ptext(I pnum) +{ + if(!plug || pnum < 0 || pnum >= plug->GetNumParams()) return; + + C display[164]; /* the Steinberg(tm) way... */ + + memset(display,0,sizeof(display)); + plug->DescribeValue(pnum,display); + + A at[2]; + SetInt(at[0],pnum); + SetString(at[1],display); + ToOutAnything(GetOutAttr(),MakeSymbol("ptext"),2,at); +} + +V vst::m_note(I note,I velocity) +{ + if(!plug) return; + + if(velocity > 0) + plug->AddNoteOn(note,velocity); + else + plug->AddNoteOff(note); +} diff --git a/externals/grill/vst/src/main.h b/externals/grill/vst/src/main.h index 5aabf360..123cad7a 100644 --- a/externals/grill/vst/src/main.h +++ b/externals/grill/vst/src/main.h @@ -1,7 +1,7 @@ /* vst - VST plugin object for PD -based on the work of mark@junklight.com +based on the work of Jarno Seppänen and Mark Williamson Copyright (c) 2003 Thomas Grill (xovo@gmx.net) For information on usage and redistribution, and for a DISCLAIMER OF ALL -- cgit v1.2.1