aboutsummaryrefslogtreecommitdiff
path: root/externals/grill/vst
diff options
context:
space:
mode:
Diffstat (limited to 'externals/grill/vst')
-rw-r--r--externals/grill/vst/license.txt4
-rw-r--r--externals/grill/vst/package.txt2
-rw-r--r--externals/grill/vst/pd/help-vst~.pd199
-rw-r--r--externals/grill/vst/readme.txt3
-rw-r--r--externals/grill/vst/src/editorwin.hpp20
-rw-r--r--externals/grill/vst/src/main.cpp489
-rw-r--r--externals/grill/vst/src/main.h12
-rw-r--r--externals/grill/vst/src/vst.rc2
-rw-r--r--externals/grill/vst/src/vstedit.cpp76
-rw-r--r--externals/grill/vst/src/vsthost.cpp938
-rw-r--r--externals/grill/vst/src/vsthost.h293
-rw-r--r--externals/grill/vst/src/vstmaster.cpp288
-rw-r--r--externals/grill/vst/src/vstmidi.cpp52
-rw-r--r--externals/grill/vst/src/vstparam.cpp105
-rw-r--r--externals/grill/vst/vst.vcproj17
15 files changed, 1404 insertions, 1096 deletions
diff --git a/externals/grill/vst/license.txt b/externals/grill/vst/license.txt
index 05faa5c3..4535110c 100644
--- a/externals/grill/vst/license.txt
+++ b/externals/grill/vst/license.txt
@@ -1,6 +1,6 @@
vst~ - VST plugin object for PD
based on the work of Jarno Seppänen and Mark Williamson
-Copyright (C) 2003 Thomas Grill
+Copyright (C) 2003-2005 Thomas Grill
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
@@ -52,7 +52,7 @@ syntax
--- flext ----------------------------------------------
flext - C++ layer for Max/MSP and pd (pure data) externals
-Copyright (C) 2001-2003 Thomas Grill
+Copyright (C) 2001-2005 Thomas Grill
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
diff --git a/externals/grill/vst/package.txt b/externals/grill/vst/package.txt
index 97f909f0..59e4c4c6 100644
--- a/externals/grill/vst/package.txt
+++ b/externals/grill/vst/package.txt
@@ -5,6 +5,6 @@ BUILDTYPE=multi
BUILDDIR=build
SRCDIR=src
-SRCS=main.cpp vsthost.cpp editor.cpp
+SRCS=main.cpp vsthost.cpp vstmaster.cpp vstedit.cpp vstparam.cpp vstmidi.cpp editor.cpp
HDRS=main.h vsthost.h editor.h editorwin.hpp editormac.hpp
diff --git a/externals/grill/vst/pd/help-vst~.pd b/externals/grill/vst/pd/help-vst~.pd
index dcf48343..a43cdb2e 100644
--- a/externals/grill/vst/pd/help-vst~.pd
+++ b/externals/grill/vst/pd/help-vst~.pd
@@ -1,8 +1,8 @@
-#N canvas 146 124 833 559 12;
+#N canvas 125 128 853 560 12;
#X obj 26 190 dac~;
#X obj 26 94 noise~;
-#X obj 140 192 print A;
-#X obj 443 431 tgl 15 0 empty empty empty 0 -6 0 8 -225271 -1 -1 1
+#X obj 93 189 print A;
+#X obj 443 431 tgl 15 0 empty empty empty 0 -6 0 8 -225271 -1 -1 0
1;
#X msg 442 453 vis \$1;
#X obj 231 430 tgl 15 0 empty empty empty 0 -6 0 8 -225271 -1 -1 1
@@ -10,32 +10,34 @@
#X msg 230 452 edit \$1;
#X msg 298 452 getedit;
#X msg 505 453 getvis;
-#N canvas 367 122 558 434 info 0;
-#X msg 94 130 getversion;
-#X msg 94 75 getname;
-#X msg 95 153 getvendor;
-#X msg 94 188 getsynth;
-#X msg 94 218 getins;
-#X msg 155 220 getouts;
-#X msg 95 104 getdll;
-#X obj 26 260 s \$0-vst;
-#X msg 100 293 print;
-#X msg 101 340 echo \$1;
-#X obj 100 323 tgl 15 0 empty empty empty 0 -6 0 8 -225271 -1 -1 0
-1;
-#X msg 173 339 getecho;
-#X text 250 321 old stuff;
-#X text 171 190 is synth?;
-#X text 179 153 get vendor string;
-#X text 181 131 get version;
-#X text 154 104 get shared lib name;
-#X text 159 79 get internal (official) plug name;
-#X text 219 221 number of plug inlets and outlets;
+#N canvas 367 122 562 438 info 0;
+#X msg 92 160 getversion;
+#X msg 92 105 getname;
+#X msg 93 183 getvendor;
+#X msg 92 218 getsynth;
+#X msg 92 248 getins;
+#X msg 153 250 getouts;
+#X msg 93 134 getdll;
+#X obj 24 290 s \$0-vst;
+#X msg 98 323 print;
+#X msg 99 370 echo \$1;
+#X obj 98 353 tgl 15 0 empty empty empty 0 -6 0 8 -225271 -1 -1 0 1
+;
+#X msg 171 369 getecho;
+#X text 248 351 old stuff;
+#X text 169 220 is synth?;
+#X text 177 183 get vendor string;
+#X text 179 161 get version;
+#X text 152 134 get shared lib name;
+#X text 157 109 get internal (official) plug name;
+#X text 217 251 number of plug inlets and outlets;
#X msg 93 41 getattributes;
-#X text 213 38 get all attributes;
-#X msg 268 189 geteditor;
-#X text 348 189 has editor?;
+#X msg 266 219 geteditor;
+#X text 346 219 has editor?;
#X msg 22 41 help;
+#X text 213 38 list all attributes;
+#X msg 93 64 getmethods;
+#X text 213 65 list all methods;
#X connect 0 0 7 0;
#X connect 1 0 7 0;
#X connect 2 0 7 0;
@@ -48,8 +50,9 @@
#X connect 10 0 9 0;
#X connect 11 0 7 0;
#X connect 19 0 7 0;
-#X connect 21 0 7 0;
-#X connect 23 0 7 0;
+#X connect 20 0 7 0;
+#X connect 22 0 7 0;
+#X connect 24 0 7 0;
#X restore 445 110 pd info;
#X obj 96 96 r \$0-vst;
#X obj 229 479 s \$0-vst;
@@ -60,11 +63,11 @@
#X obj 26 323 s \$0-vst;
#X text 65 249 set/get plugin;
#X text 511 110 further information;
-#X obj 23 15 cnv 15 750 58 empty empty vst~ 10 32 0 24 -260818 -1 0
+#X obj 23 15 cnv 15 800 58 empty empty vst~ 10 32 0 24 -260818 -1 0
;
-#X text 137 173 attribute outlet;
+#X text 90 170 attribute outlet;
#X text 103 137 inlets outlets [plugname];
-#N canvas 367 122 513 321 win 0;
+#N canvas 367 122 521 329 win 0;
#X obj 11 287 s \$0-vst;
#X msg 28 84 getx;
#X text 135 77 get window coordinates;
@@ -103,7 +106,7 @@
#X obj 27 240 bng 25 250 50 0 empty empty empty 0 -6 0 8 -225271 -1
-1;
#X obj 27 271 openpanel;
-#N canvas 461 281 498 343 midi 0;
+#N canvas 461 281 502 347 midi 0;
#X obj 20 279 s \$0-vst;
#X msg 238 147 ctlchg 3 123;
#X text 116 28 note on;
@@ -156,7 +159,7 @@
#X text 256 239 mute output;
#X msg 230 262 mute \$1;
#X msg 312 262 getmute;
-#N canvas 200 110 473 372 parameters 0;
+#N canvas 200 110 477 376 parameters 0;
#X obj 84 118 hsl 128 15 0 1 0 0 empty empty empty -2 -6 0 8 -225271
-1 -1 0 1;
#X msg 81 135 param 2 \$1;
@@ -189,7 +192,7 @@
#X connect 14 0 2 0;
#X connect 15 0 2 0;
#X restore 444 143 pd parameters;
-#N canvas 0 0 458 308 programs 0;
+#N canvas 0 0 462 312 programs 0;
#X obj 39 245 s \$0-vst;
#X msg 162 106 getprogram;
#X text 134 34 get number of programs;
@@ -224,24 +227,118 @@
#X text 562 175 VST programs;
#X text 134 53 http://grrrr.org;
#X text 513 209 midi messages for VST synths;
-#X text 448 314 Attention: this vst~ version will crash when a plugin
-is unloaded with the editor window open!;
-#X text 133 14 VST plugins for PD \, (C)2003-05 Thomas Grill;
-#X msg 27 429 subplug AudioTrack;
-#X obj 27 479 s \$0-vst;
-#X msg 39 452 getsubplug;
+#X msg 47 413 subplug AudioTrack;
+#X obj 32 498 s \$0-vst;
+#X msg 54 468 getsubplug;
#X obj 26 140 vst~ 2 2 @pnames 100;
-#X text 27 387 subplugin name for plugin shells;
#X text 229 501 you can also alt-click on the vst~ object;
-#X connect 1 0 52 0;
-#X connect 1 0 52 1;
+#X msg 32 382 getpluglist;
+#X msg 52 440 subplug C4;
+#N canvas 105 36 474 631 time 0;
+#X obj 17 225 s \$0-vst;
+#X msg 112 78 samplepos \$1;
+#X obj 111 60 nbx 5 14 0 1e+037 0 0 empty empty empty 0 -6 0 10 -225271
+-1 -1 5 256;
+#X msg 224 77 getsamplepos;
+#X obj 111 108 nbx 5 14 0 1e+037 0 0 empty empty empty 0 -6 0 10 -225271
+-1 -1 11 256;
+#X msg 112 126 ppqpos \$1;
+#X msg 199 127 getppqpos;
+#X obj 111 153 nbx 5 14 5 400 0 1 empty empty empty 0 -6 0 10 -225271
+-1 -1 120 256;
+#X msg 112 171 tempo \$1;
+#X msg 199 172 gettempo;
+#X msg 113 28 playing \$1;
+#X msg 203 28 getplaying;
+#X obj 112 -1 tgl 25 0 empty empty empty 0 -6 0 8 -225271 -1 -1 1 1
+;
+#X obj 109 218 tgl 25 0 empty empty empty 0 -6 0 8 -225271 -1 -1 1
+1;
+#X msg 110 247 looping \$1;
+#X msg 200 247 getlooping;
+#X obj 111 275 nbx 5 14 0 1e+037 0 0 empty empty empty 0 -6 0 10 -225271
+-1 -1 5 256;
+#X msg 112 293 loopstart \$1;
+#X msg 222 293 getloopstart;
+#X obj 111 319 nbx 5 14 0 1e+037 0 0 empty empty empty 0 -6 0 10 -225271
+-1 -1 35 256;
+#X msg 112 337 loopend \$1;
+#X msg 222 337 getloopend;
+#X obj 111 363 nbx 5 14 0 1e+037 0 0 empty empty empty 0 -6 0 10 -225271
+-1 -1 0 256;
+#X msg 112 379 looplength \$1;
+#X msg 227 379 getlooplength;
+#X obj 112 512 nbx 5 14 0 1e+037 0 0 empty empty empty 0 -6 0 10 -225271
+-1 -1 0 256;
+#X msg 113 528 smpteoffset \$1;
+#X msg 235 528 getsmpteoffset;
+#X msg 113 570 smpterate \$1;
+#X msg 227 570 getsmpterate;
+#X obj 113 553 hradio 15 1 0 6 empty empty empty 0 -6 0 8 -225271 -1
+-1 0;
+#X text 227 552 24/25/24/30/29.97df/30df;
+#X obj 112 415 nbx 5 14 1 128 0 1 empty empty empty 0 -6 0 10 -225271
+-1 -1 4 256;
+#X msg 113 433 timenom \$1;
+#X msg 205 434 gettimenom;
+#X obj 113 455 nbx 5 14 1 128 0 1 empty empty empty 0 -6 0 10 -225271
+-1 -1 4 256;
+#X msg 114 473 timeden \$1;
+#X msg 206 474 gettimeden;
+#X text 300 423 time signature;
+#X text 302 438 nominator;
+#X text 302 476 denominator;
+#X text 284 161 tempo in quarters per minute;
+#X connect 1 0 0 0;
+#X connect 2 0 1 0;
+#X connect 3 0 0 0;
+#X connect 4 0 5 0;
+#X connect 5 0 0 0;
+#X connect 6 0 0 0;
+#X connect 7 0 8 0;
+#X connect 8 0 0 0;
+#X connect 9 0 0 0;
+#X connect 10 0 0 0;
+#X connect 11 0 0 0;
+#X connect 12 0 10 0;
+#X connect 13 0 14 0;
+#X connect 14 0 0 0;
+#X connect 15 0 0 0;
+#X connect 16 0 17 0;
+#X connect 17 0 0 0;
+#X connect 18 0 0 0;
+#X connect 19 0 20 0;
+#X connect 20 0 0 0;
+#X connect 21 0 0 0;
+#X connect 22 0 23 0;
+#X connect 23 0 0 0;
+#X connect 24 0 0 0;
+#X connect 25 0 26 0;
+#X connect 26 0 0 0;
+#X connect 27 0 0 0;
+#X connect 28 0 0 0;
+#X connect 29 0 0 0;
+#X connect 30 0 28 0;
+#X connect 32 0 33 0;
+#X connect 33 0 0 0;
+#X connect 34 0 0 0;
+#X connect 35 0 36 0;
+#X connect 36 0 0 0;
+#X connect 37 0 0 0;
+#X restore 446 280 pd time;
+#X text 513 278 sequencer stuff;
+#X text 133 14 VST plugins for PD \, (C)2003-2005 Thomas Grill;
+#X text 443 319 Attention: this vst~ version will crash when a plugin
+is unloaded with the editor window open!;
+#X connect 1 0 50 0;
+#X connect 1 0 50 1;
#X connect 3 0 4 0;
#X connect 4 0 12 0;
#X connect 5 0 6 0;
#X connect 6 0 11 0;
#X connect 7 0 11 0;
#X connect 8 0 12 0;
-#X connect 10 0 52 0;
+#X connect 10 0 50 0;
#X connect 15 0 16 0;
#X connect 24 0 16 0;
#X connect 25 0 26 0;
@@ -253,8 +350,10 @@ is unloaded with the editor window open!;
#X connect 36 0 39 0;
#X connect 39 0 37 0;
#X connect 40 0 37 0;
-#X connect 49 0 50 0;
-#X connect 51 0 50 0;
-#X connect 52 0 0 0;
-#X connect 52 1 0 1;
-#X connect 52 2 2 0;
+#X connect 47 0 48 0;
+#X connect 49 0 48 0;
+#X connect 50 0 0 0;
+#X connect 50 1 0 1;
+#X connect 50 2 2 0;
+#X connect 52 0 48 0;
+#X connect 53 0 48 0;
diff --git a/externals/grill/vst/readme.txt b/externals/grill/vst/readme.txt
index 5c52e97f..fc55be79 100644
--- a/externals/grill/vst/readme.txt
+++ b/externals/grill/vst/readme.txt
@@ -55,6 +55,9 @@ Version history:
- pre14: allow window titles with spaces and update it on window startup
- pre18: open plug interface on Alt-Click
- pre18: experimental plug shell support
+- pre19: better shell support
+- pre19: restructured code and added time info
+- pre19: support for event processing (like MIDI in)
0.0.0:
- version of mark@junklight.com
diff --git a/externals/grill/vst/src/editorwin.hpp b/externals/grill/vst/src/editorwin.hpp
index f29313d4..29e63db6 100644
--- a/externals/grill/vst/src/editorwin.hpp
+++ b/externals/grill/vst/src/editorwin.hpp
@@ -38,7 +38,7 @@ static LRESULT CALLBACK wndproc(HWND hwnd,UINT msg,WPARAM wp,LPARAM lp)
plug->StartEditing(hwnd);
break;
case WM_CLOSE:
-#ifdef FLEXT_DEBUG
+#ifdef FLEXT_LOGGING
flext::post("WM_CLOSE");
#endif
// plug could already have been unloaded...
@@ -46,7 +46,7 @@ static LRESULT CALLBACK wndproc(HWND hwnd,UINT msg,WPARAM wp,LPARAM lp)
DestroyWindow(hwnd);
break;
case WM_DESTROY:
-#ifdef FLEXT_DEBUG
+#ifdef FLEXT_LOGGING
flext::post("WM_DESTROY");
#endif
// stop editor thread
@@ -66,7 +66,7 @@ static LRESULT CALLBACK wndproc(HWND hwnd,UINT msg,WPARAM wp,LPARAM lp)
short x = reinterpret_cast<short &>(wx),y = reinterpret_cast<short &>(wy);
// x and y are the coordinates of the client rect (= actual VST interface)
plug->SetPos(x,y,false);
-#ifdef FLEXT_DEBUG
+#ifdef FLEXT_LOGGING
flext::post("WM_MOVE x/y=%i/%i",x,y);
#endif
break;
@@ -87,7 +87,7 @@ static LRESULT CALLBACK wndproc(HWND hwnd,UINT msg,WPARAM wp,LPARAM lp)
}
#endif
-#if 0 //def FLEXT_DEBUG
+#if 0 //def FLEXT_LOGGING
case WM_SIZE: {
WORD wx = LOWORD(lp),wy = HIWORD(lp);
short x = reinterpret_cast<short &>(wx),y = reinterpret_cast<short &>(wy);
@@ -98,7 +98,7 @@ static LRESULT CALLBACK wndproc(HWND hwnd,UINT msg,WPARAM wp,LPARAM lp)
#endif
default:
- #ifdef FLEXT_DEBUG
+ #ifdef FLEXT_LOGGING
flext::post("WND MSG %i, WP=%i, lp=%i",msg,wp,lp);
#endif
@@ -169,7 +169,7 @@ static void threadfun(flext::thr_params *p)
ERect r;
plug->GetEditorRect(r);
windowsize(wnd,plug->GetX(),plug->GetY(),r.right-r.left,r.bottom-r.top,plug->GetCaption(),SWP_SHOWWINDOW);
-#ifdef FLEXT_DEBUG
+#ifdef FLEXT_LOGGING
flext::post("Editor rect left/top=%i/%i, right/bottom=%i/%i",r.left,r.top,r.right,r.bottom);
#endif
@@ -220,23 +220,23 @@ void SetupEditor()
void StartEditor(VSTPlugin *p)
{
-#ifdef FLEXT_DEBUG
+#ifdef FLEXT_LOGGING
flext::post("Start editor 1");
#endif
flext::LaunchThread(threadfun,reinterpret_cast<flext::thr_params *>(p));
-#ifdef FLEXT_DEBUG
+#ifdef FLEXT_LOGGING
flext::post("Start editor 2");
#endif
}
void StopEditor(VSTPlugin *p)
{
-#ifdef FLEXT_DEBUG
+#ifdef FLEXT_LOGGING
flext::post("Stop editor 1");
#endif
PostMessage(p->EditorHandle(),WM_CLOSE,0,0);
flext::StopThread(threadfun,reinterpret_cast<flext::thr_params *>(p));
-#ifdef FLEXT_DEBUG
+#ifdef FLEXT_LOGGING
flext::post("Stop editor 2");
#endif
}
diff --git a/externals/grill/vst/src/main.cpp b/externals/grill/vst/src/main.cpp
index 75b5feda..1292a746 100644
--- a/externals/grill/vst/src/main.cpp
+++ b/externals/grill/vst/src/main.cpp
@@ -26,109 +26,142 @@ WARRANTIES, see the file, "license.txt," in this distribution.
#endif
-#define VST_VERSION "0.1.0pre18"
+#define VST_VERSION "0.1.0pre19"
-class vst:
- public flext_dsp
+class vst
+ : public flext_dsp
+ , public Responder
{
FLEXT_HEADER_S(vst,flext_dsp,Setup)
public:
- vst(I argc,const A *argv);
+ vst(int argc,const t_atom *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);
+ virtual void m_dsp(int n,t_signalvec const *insigs,t_signalvec const *outsigs);
+ virtual void m_signal(int n,t_sample *const *insigs,t_sample *const *outsigs);
virtual void m_click() { ms_edit(true); }
- 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.c_str()); }
+ bool ms_plug(int argc,const t_atom *argv);
+ bool ms_plug(const AtomList &args) { return ms_plug(args.Count(),args.Atoms()); }
+ void mg_plug(AtomList &sym) const { sym(1); SetString(sym[0],plugname.c_str()); }
- void ms_subplug(I argc,const A *argv);
+ void ms_subplug(int argc,const t_atom *argv);
void ms_subplug(const AtomList &args) { ms_subplug(args.Count(),args.Atoms()); }
void mg_subplug(AtomList &sym) const { sym(1); SetString(sym[0],subplug.c_str()); }
- V mg_editor(BL &ed) { ed = plug && plug->HasEditor(); }
-
- V ms_edit(BL on) { if(plug) plug->Edit(on); }
- V mg_edit(BL &ed) { ed = plug && plug->IsEdited(); }
- V ms_vis(BL vis) { if(plug) plug->Visible(vis); }
- V mg_vis(BL &vis) { vis = plug && plug->IsVisible(); }
-
- 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 ms_wincaption(bool c) { if(plug) plug->SetCaption(c); }
- V mg_wincaption(bool &c) const { c = plug && plug->GetCaption(); }
- V ms_wintitle(const AtomList &t);
- V mg_wintitle(AtomList &t) const { if(plug) { t(1); SetString(t[0],plug->GetTitle()); } }
-
- 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->GetNumPrograms():0; }
- V mg_progcats(I &p) const { p = plug?plug->GetNumCategories():0; }
- V mg_plugname(const S *&s) const { s = plug?MakeSymbol(plug->GetName()):sym__; }
- V mg_plugvendor(const S *&s) const { s = plug?MakeSymbol(plug->GetVendorName()):sym__; }
- V mg_plugdll(const S *&s) const { s = plug?MakeSymbol(plug->GetDllName()):sym__; }
- 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 mg_progname(int argc,const t_atom *argv) const;
+ void m_pluglist() { if(plug) plug->ListPlugs(sym_pluglist); }
+
+ void mg_editor(bool &ed) { ed = plug && plug->HasEditor(); }
+
+ void ms_edit(bool on) { if(plug) plug->Edit(on); }
+ void mg_edit(bool &ed) { ed = plug && plug->IsEdited(); }
+ void ms_vis(bool vis) { if(plug) plug->Visible(vis); }
+ void mg_vis(bool &vis) { vis = plug && plug->IsVisible(); }
+
+ void mg_winx(int &x) const { x = plug?plug->GetX():0; }
+ void mg_winy(int &y) const { y = plug?plug->GetY():0; }
+ void ms_winx(int x) { if(plug) plug->SetX(x); }
+ void ms_winy(int y) { if(plug) plug->SetY(y); }
+ void ms_wincaption(bool c) { if(plug) plug->SetCaption(c); }
+ void mg_wincaption(bool &c) const { c = plug && plug->GetCaption(); }
+ void ms_wintitle(const AtomList &t);
+ void mg_wintitle(AtomList &t) const { if(plug) { t(1); SetString(t[0],plug->GetTitle()); } }
+
+ void mg_chnsin(int &c) const { c = plug?plug->GetNumInputs():0; }
+ void mg_chnsout(int &c) const { c = plug?plug->GetNumOutputs():0; }
+ void mg_params(int &p) const { p = plug?plug->GetNumParams():0; }
+ void mg_programs(int &p) const { p = plug?plug->GetNumPrograms():0; }
+ void mg_progcats(int &p) const { p = plug?plug->GetNumCategories():0; }
+ void mg_plugname(const t_symbol *&s) const { s = plug?MakeSymbol(plug->GetName()):sym__; }
+ void mg_plugvendor(const t_symbol *&s) const { s = plug?MakeSymbol(plug->GetVendorName()):sym__; }
+ void mg_plugdll(const t_symbol *&s) const { s = plug?MakeSymbol(plug->GetDllName()):sym__; }
+ void mg_plugversion(int &v) const { v = plug?plug->GetVersion():0; }
+ void mg_issynth(bool &s) const { s = plug && plug->IsSynth(); }
+
+ void m_print(int ac,const t_atom *av);
+
+ void ms_program(int p) { if(plug && p >= 0) plug->SetCurrentProgram(p); }
+ void mg_program(int &p) const { p = plug?plug->GetCurrentProgram():0; }
+ void 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);
- 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); }
+ void m_pname(int pnum);
+ void ms_paramnames(int cnt) { paramnames = cnt; if(plug) plug->ScanParams(cnt); }
+
+ void ms_param(int pnum,float val);
+ void ms_params(int argc,const t_atom *argv);
+ void mg_param(int pnum);
+ void mg_params(int argc,const t_atom *argv);
+ void m_ptext(int pnum);
+ void m_ptexts(int argc,const t_atom *argv);
+
+// void m_control(const t_symbol *ctrl_name,int ctrl_value);
+ void m_pitchbend(int ctrl_value) { if(plug) plug->AddPitchBend(ctrl_value ); }
+ void m_programchange(int ctrl_value) { if(plug) plug->AddProgramChange(ctrl_value ); }
+ void m_aftertouch(int ctrl_value) { if(plug) plug->AddAftertouch(ctrl_value ); }
+ void m_ctrlchange(int control,int ctrl_value) { if(plug) plug->AddControlChange(control,ctrl_value ); }
+ void m_note(int note,int vel);
+ void m_noteoff(int note) { m_note(note,0); }
+
+ void mg_playing(bool &p) { p = plug && plug->GetPlaying(); }
+ void ms_playing(bool p) { if(plug) plug->SetPlaying(p); }
+ void mg_looping(bool &p) { p = plug && plug->GetLooping(); }
+ void ms_looping(bool p) { if(plug) plug->SetLooping(p); }
+ void mg_samplepos(float &p) { p = plug?(float)plug->GetSamplePos():0; }
+ void ms_samplepos(float p) { if(plug) plug->SetSamplePos(p); }
+ void mg_ppqpos(float &p) { p = plug?(float)plug->GetPPQPos():0; }
+ void ms_ppqpos(float p) { if(plug) plug->SetPPQPos(p); }
+ void mg_tempo(float &p) { p = plug?(float)plug->GetTempo():0; }
+ void ms_tempo(float p) { if(plug) plug->SetTempo(p); }
+ void mg_barstart(float &p) { p = plug?(float)plug->GetBarStart():0; }
+ void ms_barstart(float p) { if(plug) plug->SetBarStart(p); }
+ void mg_cyclestart(float &p) { p = plug?(float)plug->GetCycleStart():0; }
+ void ms_cyclestart(float p) { if(plug) plug->SetCycleStart(p); }
+ void mg_cycleend(float &p) { p = plug?(float)plug->GetCycleEnd():0; }
+ void ms_cycleend(float p) { if(plug) plug->SetCycleEnd(p); }
+ void mg_cyclelength(float &p) { p = plug?(float)(plug->GetCycleEnd()-plug->GetCycleStart()):0; }
+ void ms_cyclelength(float p) { if(p) plug->SetCycleEnd(plug->GetCycleStart()+p); }
+ void mg_timesignom(int &p) { p = plug?plug->GetTimesigNom():0; }
+ void ms_timesignom(int p) { if(plug) plug->SetTimesigNom(p); }
+ void mg_timesigden(int &p) { p = plug?plug->GetTimesigDen():0; }
+ void ms_timesigden(int p) { if(plug) plug->SetTimesigDen(p); }
+ void mg_smpteoffset(int &p) { p = plug?plug->GetSmpteOffset():0; }
+ void ms_smpteoffset(int p) { if(plug) plug->SetSmpteOffset(p); }
+ void mg_smpterate(int &p) { p = plug?plug->GetSmpteRate():0; }
+ void ms_smpterate(int p) { if(plug) plug->SetSmpteRate(p); }
private:
- V display_parameter(I param,BL showparams);
+ void display_parameter(int param,bool showparams);
VSTPlugin *plug;
std::string plugname,subplug;
bool echoparam,visible,bypass,mute;
int paramnames;
- I blsz;
- V (VSTPlugin::*vstfun)(R **insigs,R **outsigs,L n);
- BL sigmatch;
- R **vstin,**vstout,**tmpin,**tmpout;
+ int blsz;
+ void (VSTPlugin::*vstfun)(t_sample **insigs,t_sample **outsigs,long n);
+ bool sigmatch;
+ t_sample **vstin,**vstout,**tmpin,**tmpout;
- V InitPlug();
- V ClearPlug();
- V InitPlugDSP();
- V InitBuf();
- V ClearBuf();
+ void InitPlug();
+ void ClearPlug();
+ bool LoadPlug();
+ void InitPlugDSP();
+ void InitBuf();
+ void ClearBuf();
- static V Setup(t_classid);
+ static void Setup(t_classid);
+ virtual void Respond(const t_symbol *sym,int argc = 0,const t_atom *argv = NULL);
FLEXT_CALLBACK_V(m_print)
FLEXT_CALLVAR_V(mg_plug,ms_plug)
FLEXT_CALLVAR_V(mg_subplug,ms_subplug)
+ FLEXT_CALLBACK(m_pluglist)
FLEXT_CALLVAR_B(mg_edit,ms_edit)
FLEXT_CALLGET_B(mg_editor)
@@ -175,15 +208,29 @@ private:
FLEXT_CALLGET_I(mg_plugversion)
FLEXT_CALLGET_B(mg_issynth)
- static const t_symbol *sym_progname,*sym_pname,*sym_param,*sym_ptext;
+ FLEXT_CALLVAR_B(mg_playing,ms_playing)
+ FLEXT_CALLVAR_B(mg_looping,ms_looping)
+ FLEXT_CALLVAR_F(mg_samplepos,ms_samplepos)
+ FLEXT_CALLVAR_F(mg_ppqpos,ms_ppqpos)
+ FLEXT_CALLVAR_F(mg_tempo,ms_tempo)
+ FLEXT_CALLVAR_F(mg_barstart,ms_barstart)
+ FLEXT_CALLVAR_F(mg_cyclestart,ms_cyclestart)
+ FLEXT_CALLVAR_F(mg_cycleend,ms_cycleend)
+ FLEXT_CALLVAR_F(mg_cyclelength,ms_cyclelength)
+ FLEXT_CALLVAR_I(mg_timesignom,ms_timesignom)
+ FLEXT_CALLVAR_I(mg_timesigden,ms_timesigden)
+ FLEXT_CALLVAR_I(mg_smpteoffset,ms_smpteoffset)
+ FLEXT_CALLVAR_I(mg_smpterate,ms_smpterate)
+
+ static const t_symbol *sym_progname,*sym_pname,*sym_param,*sym_ptext,*sym_pluglist;
};
FLEXT_NEW_DSP_V("vst~",vst);
-const t_symbol *vst::sym_progname,*vst::sym_pname,*vst::sym_param,*vst::sym_ptext;
+const t_symbol *vst::sym_progname,*vst::sym_pname,*vst::sym_param,*vst::sym_ptext,*vst::sym_pluglist;
-V vst::Setup(t_classid c)
+void vst::Setup(t_classid c)
{
post("");
post("vst~ %s - VST plugin object, (C)2003-05 Thomas Grill",VST_VERSION);
@@ -192,6 +239,7 @@ V vst::Setup(t_classid c)
FLEXT_CADDATTR_VAR(c,"plug",mg_plug,ms_plug);
FLEXT_CADDATTR_VAR(c,"subplug",mg_subplug,ms_subplug);
+ FLEXT_CADDMETHOD_(c,0,"getpluglist",m_pluglist);
FLEXT_CADDATTR_VAR(c,"edit",mg_edit,ms_edit);
FLEXT_CADDATTR_GET(c,"editor",mg_editor);
FLEXT_CADDATTR_VAR(c,"vis",mg_vis,ms_vis);
@@ -236,34 +284,50 @@ V vst::Setup(t_classid c)
FLEXT_CADDATTR_GET(c,"version",mg_plugversion);
FLEXT_CADDATTR_GET(c,"synth",mg_issynth);
+ FLEXT_CADDATTR_VAR(c,"playing",mg_playing,ms_playing);
+ FLEXT_CADDATTR_VAR(c,"looping",mg_looping,ms_looping);
+ FLEXT_CADDATTR_VAR(c,"samplepos",mg_samplepos,ms_samplepos);
+ FLEXT_CADDATTR_VAR(c,"ppqpos",mg_ppqpos,ms_ppqpos);
+ FLEXT_CADDATTR_VAR(c,"tempo",mg_tempo,ms_tempo);
+ FLEXT_CADDATTR_VAR(c,"barstart",mg_barstart,ms_barstart);
+ FLEXT_CADDATTR_VAR(c,"loopstart",mg_cyclestart,ms_cyclestart);
+ FLEXT_CADDATTR_VAR(c,"loopend",mg_cycleend,ms_cycleend);
+ FLEXT_CADDATTR_VAR(c,"looplength",mg_cyclelength,ms_cyclelength);
+ FLEXT_CADDATTR_VAR(c,"timenom",mg_timesignom,ms_timesignom);
+ FLEXT_CADDATTR_VAR(c,"timeden",mg_timesigden,ms_timesigden);
+ FLEXT_CADDATTR_VAR(c,"smpteoffset",mg_smpteoffset,ms_smpteoffset);
+ FLEXT_CADDATTR_VAR(c,"smpterate",mg_smpterate,ms_smpterate);
+
sym_progname = MakeSymbol("progname");
sym_pname = MakeSymbol("pname");
sym_param = MakeSymbol("param");
sym_ptext = MakeSymbol("ptext");
+ sym_pluglist = MakeSymbol("pluglist");
+ VSTPlugin::Setup();
SetupEditor();
}
-vst::vst(I argc,const A *argv):
+vst::vst(int argc,const t_atom *argv):
plug(NULL),visible(false),
blsz(0),
vstfun(NULL),vstin(NULL),vstout(NULL),tmpin(NULL),tmpout(NULL),
echoparam(false),bypass(false),mute(false),paramnames(0)
{
- if(argc >= 2 && CanbeInt(argv[0]) && CanbeInt(argv[1])) {
- AddInSignal(GetAInt(argv[0]));
- AddOutSignal(GetAInt(argv[1]));
-
- if(argc >= 3 && !ms_plug(argc-2,argv+2)) InitProblem();
- }
- else
- throw "syntax: vst~ inputs outputs [plug]";
-
#if FLEXT_OS == FLEXT_OS_WIN
// this is necessary for Waveshell
CoInitializeEx(NULL,COINIT_MULTITHREADED+COINIT_SPEED_OVER_MEMORY);
#endif
+
+ int ins = 1,outs = 1;
+ if(argc >= 1 && CanbeInt(argv[0])) { ins = GetAInt(argv[0]); argc--,argv++; }
+ if(argc >= 1 && CanbeInt(argv[0])) { outs = GetAInt(argv[0]); argc--,argv++; }
+
+ AddInSignal(ins);
+ AddOutSignal(outs);
+
+ if(argc >= 1 && !ms_plug(argc,argv)) InitProblem();
}
vst::~vst()
@@ -274,7 +338,7 @@ vst::~vst()
#endif
}
-V vst::ClearPlug()
+void vst::ClearPlug()
{
if(plug) {
plug->Edit(false);
@@ -283,7 +347,7 @@ V vst::ClearPlug()
}
}
-V vst::InitPlug()
+void vst::InitPlug()
{
FLEXT_ASSERT(plug);
@@ -296,7 +360,7 @@ V vst::InitPlug()
plug->ScanParams(paramnames);
}
-V vst::InitPlugDSP()
+void vst::InitPlugDSP()
{
FLEXT_ASSERT(plug);
// this might be invalid if DSP is switched off,
@@ -304,36 +368,36 @@ V vst::InitPlugDSP()
plug->DspInit(Samplerate(),Blocksize());
}
-V vst::ClearBuf()
+void vst::ClearBuf()
{
if(!plug) return;
if(vstin) {
- for(I i = 0; i < plug->GetNumInputs(); ++i) FreeAligned(vstin[i]);
+ for(int i = 0; i < plug->GetNumInputs(); ++i) FreeAligned(vstin[i]);
delete[] vstin; vstin = NULL;
delete[] tmpin; tmpin = NULL;
}
if(vstout) {
- for(I i = 0; i < plug->GetNumOutputs(); ++i) FreeAligned(vstout[i]);
+ for(int i = 0; i < plug->GetNumOutputs(); ++i) FreeAligned(vstout[i]);
delete[] vstout; vstout = NULL;
delete[] tmpout; tmpout = NULL;
}
}
-V vst::InitBuf()
+void vst::InitBuf()
{
FLEXT_ASSERT(!vstin && !tmpin && !vstout && !tmpout);
const int inputs = plug->GetNumInputs(),outputs = plug->GetNumOutputs();
- I i;
+ int i;
- vstin = new R *[inputs];
- tmpin = new R *[inputs];
- for(i = 0; i < inputs; ++i) vstin[i] = (R *)NewAligned(Blocksize()*sizeof(R));
+ vstin = new t_sample *[inputs];
+ tmpin = new t_sample *[inputs];
+ for(i = 0; i < inputs; ++i) vstin[i] = (t_sample *)NewAligned(Blocksize()*sizeof(t_sample));
- vstout = new R *[outputs];
- tmpout = new R *[outputs];
- for(i = 0; i < outputs; ++i) vstout[i] = (R *)NewAligned(Blocksize()*sizeof(R));
+ vstout = new t_sample *[outputs];
+ tmpout = new t_sample *[outputs];
+ for(i = 0; i < outputs; ++i) vstout[i] = (t_sample *)NewAligned(Blocksize()*sizeof(t_sample));
}
static std::string findFilePath(const std::string &path,const std::string &dllname)
@@ -372,52 +436,21 @@ static std::string findFilePath(const std::string &path,const std::string &dllna
}
-BL vst::ms_plug(I argc,const A *argv)
+bool vst::LoadPlug()
{
- ClearPlug();
-
- plugname.clear();
- C buf[255];
- for(I i = 0; i < argc; i++) {
- if(i > 0) plugname += ' ';
- GetAString(argv[i],buf,sizeof buf);
-#if FLEXT_OS == FLEXT_OS_WIN
- strlwr(buf);
-#endif
-
-#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;
- }
-
- if(!plugname.length()) return false;
+ if(plug) ClearPlug();
- 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;
+ plug = new VSTPlugin(this);
// try loading the dll from the raw filename
- if ((loaderr = plug->Instance(plugname.c_str(),subplug.c_str())) == 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.c_str(),".dll",dir,&name,sizeof(dir)-1,0);
+ bool ok = plug->Instance(plugname.c_str(),subplug.c_str());
+ if(ok)
+ FLEXT_LOG("raw filename loaded fine");
+ else {
+#if FLEXT_SYS == FLEXT_SYS_PD
+ // try finding it on the PD path
+ char *name,dir[1024];
+ int fd = open_via_path("",plugname.c_str(),".dll",dir,&name,sizeof(dir)-1,0);
if(fd > 0) close(fd);
else name = NULL;
@@ -430,35 +463,38 @@ BL vst::ms_plug(I argc,const A *argv)
dllname += "\\";
dllname += name;
- lf = (loaderr = plug->Instance(dllname.c_str())) == VSTINSTANCE_NO_ERROR;
+ ok = plug->Instance(dllname.c_str());
}
+#endif
}
- if(!lf) { // try finding it on the VST path
- C *vst_path = getenv("VST_PATH");
+ if(!ok) {
+ // try finding it on the VST path
+ char *vst_path = getenv("VST_PATH");
std::string 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];
+ char* tok_path = new char[strlen( vst_path)+1];
strcpy( tok_path , vst_path);
char *tok = strtok( tok_path , ";" );
while( tok != NULL ) {
std::string abpath( tok );
if( abpath[abpath.length()-1] != '\\' ) abpath += "\\";
- FLEXT_LOG1("trying VST_PATH %s",(const C *)abpath.c_str());
+ FLEXT_LOG1("trying VST_PATH %s",(const char *)abpath.c_str());
std::string realpath = findFilePath( abpath , dllname );
//post( "findFilePath( %s , %s ) = %s\n" , abpath , dllname , realpath );
if ( realpath.length() ) {
realpath += plugname;
- FLEXT_LOG1("trying %s",(const C *)realpath.c_str());
- if((loaderr = plug->Instance( realpath.c_str() )) == VSTINSTANCE_NO_ERROR ) {
+ FLEXT_LOG1("trying %s",(const char *)realpath.c_str());
+
+ ok = plug->Instance(realpath.c_str());
+ if(ok) {
FLEXT_LOG("plugin loaded via VST_PATH");
- lf = true;
break;
}
}
@@ -471,39 +507,65 @@ BL vst::ms_plug(I argc,const A *argv)
}
}
- if(!lf) { // failed - don't make any ins or outs
- post("%s - unable to load plugin '%s', load error %i",thisName(),plugname.c_str(),loaderr);
+ if(!ok) {
+ post("%s - unable to load plugin '%s'",thisName(),plugname.c_str());
ClearPlug();
- }
+ }
+ else
+ InitPlug();
+
+ return ok;
+}
+
+static char *stripesc(char *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
+ return buf;
+}
- // re-init dsp stuff
- if(plug) InitPlug();
+bool vst::ms_plug(int argc,const t_atom *argv)
+{
+ ClearPlug();
- return lf;
+ plugname.clear();
+ char buf[255];
+ for(int i = 0; i < argc; i++) {
+ if(i > 0) plugname += ' ';
+ GetAString(argv[i],buf,sizeof buf);
+#if FLEXT_OS == FLEXT_OS_WIN
+ strlwr(buf);
+#endif
+ plugname += stripesc(buf);
+ }
+
+ if(!plugname.length())
+ return false;
+ else
+ return LoadPlug();
}
-void vst::ms_subplug(I argc,const A *argv)
+void vst::ms_subplug(int argc,const t_atom *argv)
{
subplug.clear();
- C buf[255];
- for(I i = 0; i < argc; i++) {
+ char buf[255];
+ for(int i = 0; i < argc; i++) {
if(i > 0) subplug += ' ';
GetAString(argv[i],buf,sizeof 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
- subplug += buf;
+ subplug += stripesc(buf);
}
+
+ LoadPlug();
}
-V vst::m_dsp(I n,t_signalvec const *,t_signalvec const *)
+void vst::m_dsp(int n,t_signalvec const *,t_signalvec const *)
{
if(plug) {
FLEXT_ASSERT(vstfun);
@@ -518,7 +580,7 @@ V vst::m_dsp(I n,t_signalvec const *,t_signalvec const *)
}
}
-V vst::m_signal(I n,R *const *insigs,R *const *outsigs)
+void vst::m_signal(int n,t_sample *const *insigs,t_sample *const *outsigs)
{
if(mute)
flext_dsp::m_signal(n,insigs,outsigs);
@@ -532,10 +594,10 @@ V vst::m_signal(I n,R *const *insigs,R *const *outsigs)
i = 1;
}
else if(mx == 2) {
- R *o1 = outsigs[0],*o2 = outsigs[1];
- const R *i1 = insigs[0],*i2 = insigs[1];
+ t_sample *o1 = outsigs[0],*o2 = outsigs[1];
+ const t_sample *i1 = insigs[0],*i2 = insigs[1];
for(int s = 0; s < n; ++s) {
- const R f = *(i1++);
+ const t_sample f = *(i1++);
*(o2++) = *(i2++);
*(o1++) = f;
}
@@ -555,16 +617,16 @@ V vst::m_signal(I n,R *const *insigs,R *const *outsigs)
const int inputs = plug->GetNumInputs(),outputs = plug->GetNumOutputs();
if(sigmatch)
- (plug->*vstfun)(const_cast<R **>(insigs),const_cast<R **>(outsigs),n);
+ (plug->*vstfun)(const_cast<t_sample **>(insigs),const_cast<t_sample **>(outsigs),n);
else {
const int cntin = CntInSig(),cntout = CntOutSig();
- R **inv,**outv;
+ t_sample **inv,**outv;
if(inputs <= cntin)
- inv = const_cast<R **>(insigs);
+ inv = const_cast<t_sample **>(insigs);
else { // more plug inputs than inlets
- I i;
- for(i = 0; i < cntin; ++i) tmpin[i] = const_cast<R *>(insigs[i]);
+ int i;
+ for(i = 0; i < cntin; ++i) tmpin[i] = const_cast<t_sample *>(insigs[i]);
// set dangling inputs to zero
// according to mode... (e.g. set zero)
@@ -573,11 +635,11 @@ V vst::m_signal(I n,R *const *insigs,R *const *outsigs)
inv = tmpin;
}
- const BL more = outputs <= cntout;
+ const bool more = outputs <= cntout;
if(more) // more outlets than plug outputs
- outv = const_cast<R **>(outsigs);
+ outv = const_cast<t_sample **>(outsigs);
else {
- I i;
+ int i;
for(i = 0; i < cntout; ++i) tmpout[i] = outsigs[i];
for(; i < outputs; ++i) tmpout[i] = vstout[i];
@@ -603,11 +665,11 @@ V vst::m_signal(I n,R *const *insigs,R *const *outsigs)
#if 0
-V vst::m_control(const S *ctrl_name,I ctrl_value)
+void vst::m_control(const t_symbol *ctrl_name,int ctrl_value)
{
if(!plug) return;
- I parm_num = 0;
+ int parm_num = 0;
if (!*GetString(ctrl_name) || !strlen(GetString(ctrl_name))) {
error ("plugin~: control messages must have a name and a value");
@@ -626,26 +688,6 @@ V vst::m_control(const S *ctrl_name,I 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);
-}
-
void vst::mg_progname(int argc,const t_atom *argv) const
{
if(plug) {
@@ -662,7 +704,7 @@ void vst::mg_progname(int argc,const t_atom *argv) const
char str[256];
plug->GetProgramName(cat,pnum,str);
- A at[3];
+ t_atom at[3];
SetInt(at[0],cat);
SetInt(at[1],pnum);
SetString(at[2],str);
@@ -673,12 +715,7 @@ void vst::mg_progname(int argc,const t_atom *argv) const
}
}
-V vst::m_ctrlchange(I control,I ctrl_value)
-{
- if(plug) plug->AddControlChange(control,ctrl_value );
-}
-
-V vst::ms_wintitle(const AtomList &t)
+void vst::ms_wintitle(const AtomList &t)
{
if(plug) {
char txt[256];
@@ -692,7 +729,7 @@ V vst::ms_wintitle(const AtomList &t)
* may be of use
*/
-V vst::m_print(I ac,const A *av)
+void vst::m_print(int ac,const t_atom *av)
{
if(!plug) return;
@@ -705,7 +742,7 @@ V vst::m_print(I ac,const A *av)
if( ac > 0 ) {
for( i = 0 ; i < ac ; i++) {
if(IsString(av[i])) {
- const C *buf = GetString(av[i]);
+ const char *buf = GetString(av[i]);
if ( strcmp( buf , "-params" ) == 0 ) {
params = true;
}
@@ -773,7 +810,7 @@ V vst::m_print(I ac,const A *av)
}
-V vst::display_parameter(I param,BL showparams)
+void vst::display_parameter(int param,bool showparams)
{
int j = param;
/* the Steinberg(tm) way... */
@@ -801,25 +838,25 @@ V vst::display_parameter(I param,BL showparams)
}
}
-V vst::m_pname(I pnum)
+void vst::m_pname(int pnum)
{
if(!plug || pnum < 0 || pnum >= plug->GetNumParams()) return;
char name[256]; // how many chars needed?
plug->GetParamName(pnum,name);
- A at[2];
+ t_atom 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)
+void vst::ms_param(int pnum,float val)
{
if(!plug || pnum < 0 || pnum >= plug->GetNumParams()) return;
- F xval = plug->GetParamValue( pnum );
+ float xval = plug->GetParamValue( pnum );
// if(xval <= 1.0f) // What's that????
if(true)
{
@@ -849,17 +886,17 @@ void vst::ms_params(int argc,const t_atom *argv)
}
}
-V vst::mg_param(I pnum)
+void vst::mg_param(int pnum)
{
if(!plug || pnum < 0 || pnum >= plug->GetNumParams()) return;
- A at[2];
+ t_atom at[2];
SetInt(at[0],pnum);
SetFloat(at[1],plug->GetParamValue(pnum));
ToOutAnything(GetOutAttr(),sym_param,2,at);
}
-V vst::mg_params(int argc,const t_atom *argv)
+void vst::mg_params(int argc,const t_atom *argv)
{
if(plug) {
char str[255];
@@ -877,7 +914,7 @@ V vst::mg_params(int argc,const t_atom *argv)
}
}
-V vst::m_ptext(I pnum)
+void vst::m_ptext(int pnum)
{
if(!plug || pnum < 0 || pnum >= plug->GetNumParams()) return;
@@ -885,13 +922,13 @@ V vst::m_ptext(I pnum)
memset(display,0,sizeof(display));
plug->GetParamValue(pnum,display);
- A at[2];
+ t_atom at[2];
SetInt(at[0],pnum);
SetString(at[1],display);
ToOutAnything(GetOutAttr(),sym_ptext,2,at);
}
-V vst::m_ptexts(int argc,const t_atom *argv)
+void vst::m_ptexts(int argc,const t_atom *argv)
{
if(plug) {
char str[255];
@@ -909,7 +946,7 @@ V vst::m_ptexts(int argc,const t_atom *argv)
}
}
-V vst::m_note(I note,I velocity)
+void vst::m_note(int note,int velocity)
{
if(!plug) return;
@@ -918,3 +955,9 @@ V vst::m_note(I note,I velocity)
else
plug->AddNoteOff(note);
}
+
+void vst::Respond(const t_symbol *sym,int argc,const t_atom *argv)
+{
+ FLEXT_ASSERT(sym);
+ ToOutAnything(GetOutAttr(),sym,argc,argv);
+}
diff --git a/externals/grill/vst/src/main.h b/externals/grill/vst/src/main.h
index fab6b622..ffd138ec 100644
--- a/externals/grill/vst/src/main.h
+++ b/externals/grill/vst/src/main.h
@@ -24,17 +24,5 @@ WARRANTIES, see the file, "license.txt," in this distribution.
#error Platform not supported!
#endif
-typedef void V;
-typedef int I;
-typedef long L;
-typedef unsigned long UL;
-typedef float F;
-typedef t_sample R;
-typedef char C;
-typedef bool BL;
-typedef t_atom A;
-typedef t_symbol S;
-
-
#endif
diff --git a/externals/grill/vst/src/vst.rc b/externals/grill/vst/src/vst.rc
index bc1a1b94..8f8e368b 100644
--- a/externals/grill/vst/src/vst.rc
+++ b/externals/grill/vst/src/vst.rc
@@ -46,7 +46,7 @@ BEGIN
VALUE "FileDescription", "vst~ external"
VALUE "FileVersion", "0,1, 0, 8"
VALUE "InternalName", "vst~"
- VALUE "LegalCopyright", "Copyright (C) 2003-2004 Thomas Grill"
+ VALUE "LegalCopyright", "Copyright (C) 2003-2005 Thomas Grill"
VALUE "OriginalFilename", "vst~.DLL"
VALUE "ProductName", "VST plugin object"
VALUE "ProductVersion", "0, 1, 0, 8"
diff --git a/externals/grill/vst/src/vstedit.cpp b/externals/grill/vst/src/vstedit.cpp
new file mode 100644
index 00000000..804e83ca
--- /dev/null
+++ b/externals/grill/vst/src/vstedit.cpp
@@ -0,0 +1,76 @@
+/*
+vst~ - VST plugin object for PD
+based on the work of Jarno Seppänen and Mark Williamson
+
+Copyright (c)2003-2005 Thomas Grill (gr@grrrr.org)
+For information on usage and redistribution, and for a DISCLAIMER OF ALL
+WARRANTIES, see the file, "license.txt," in this distribution.
+*/
+
+#include "vsthost.h"
+#include "editor.h"
+
+
+void VSTPlugin::Edit(bool open)
+{
+ if(Is()) {
+ if(open) {
+ if(HasEditor() && !IsEdited())
+ StartEditor(this);
+ }
+ else if(IsEdited())
+ StopEditor(this);
+ }
+}
+
+void VSTPlugin::StartEditing(WHandle h)
+{
+ FLEXT_ASSERT(h != NULL);
+ Dispatch(effEditOpen,0,0,hwnd = h);
+// Dispatch(effEditTop);
+
+ TitleEditor(this,title.c_str());
+}
+
+void VSTPlugin::StopEditing()
+{
+ if(Is()) {
+ Dispatch(effEditClose);
+ hwnd = NULL;
+ }
+}
+
+void VSTPlugin::Visible(bool vis)
+{
+ if(Is() && IsEdited()) ShowEditor(this,vis);
+}
+
+bool VSTPlugin::IsVisible() const
+{
+ return Is() && IsEdited() && IsEditorShown(this);
+}
+
+
+void VSTPlugin::SetPos(int x,int y,bool upd)
+{
+ if(Is()) {
+ posx = x; posy = y;
+ if(upd && IsEdited()) MoveEditor(this,posx,posy);
+ }
+}
+
+void VSTPlugin::SetCaption(bool c)
+{
+ if(Is()) {
+ caption = c;
+ if(IsEdited()) CaptionEditor(this,c);
+ }
+}
+
+void VSTPlugin::SetTitle(const char *t)
+{
+ if(Is()) {
+ title = t;
+ if(IsEdited()) TitleEditor(this,t);
+ }
+}
diff --git a/externals/grill/vst/src/vsthost.cpp b/externals/grill/vst/src/vsthost.cpp
index 0d883cd9..2c4f0643 100644
--- a/externals/grill/vst/src/vsthost.cpp
+++ b/externals/grill/vst/src/vsthost.cpp
@@ -2,94 +2,113 @@
vst~ - VST plugin object for PD
based on the work of Jarno Seppänen and Mark Williamson
-Copyright (c)2003-2004 Thomas Grill (xovo@gmx.net)
+Copyright (c)2003-2005 Thomas Grill (gr@grrrr.org)
For information on usage and redistribution, and for a DISCLAIMER OF ALL
WARRANTIES, see the file, "license.txt," in this distribution.
*/
-#include "editor.h"
#include "vsthost.h"
-#include "AEffectx.h"
-#include <ctype.h>
-typedef AEffect *(VSTCALLBACK *PVSTMAIN)(audioMasterCallback audioMaster);
-
-
-
-VSTPlugin::VSTPlugin():
- h_dll(NULL),hwnd(NULL),_pEffect(NULL),
- posx(0),posy(0),caption(true),
- _midichannel(0),queue_size(0),
- paramnamecnt(0)
+const t_symbol
+ *VSTPlugin::sym_event,
+ *VSTPlugin::sym_evmidi,
+ *VSTPlugin::sym_evaudio,
+ *VSTPlugin::sym_evvideo,
+ *VSTPlugin::sym_evparam,
+ *VSTPlugin::sym_evtrigger,
+ *VSTPlugin::sym_evsysex,
+ *VSTPlugin::sym_ev_,
+ *VSTPlugin::sym_midi[8];
+
+void VSTPlugin::Setup()
+{
+ sym_event = flext::MakeSymbol("event");
+ sym_evmidi = flext::MakeSymbol("midi");
+ sym_evaudio = flext::MakeSymbol("audio");
+ sym_evvideo = flext::MakeSymbol("video");
+ sym_evparam = flext::MakeSymbol("param");
+ sym_evtrigger = flext::MakeSymbol("trigger");
+ sym_evsysex = flext::MakeSymbol("sysex");
+ sym_ev_ = flext::MakeSymbol("???");
+
+ sym_midi[0] = flext::MakeSymbol("noteon");
+ sym_midi[1] = flext::MakeSymbol("noteoff");
+ sym_midi[2] = flext::MakeSymbol("polyafter");
+ sym_midi[3] = flext::MakeSymbol("cntl");
+ sym_midi[4] = flext::MakeSymbol("progchg");
+ sym_midi[5] = flext::MakeSymbol("chnafter");
+ sym_midi[6] = flext::MakeSymbol("pitchbend");
+ sym_midi[7] = sym__;
+}
+
+VSTPlugin::VSTPlugin(Responder *resp)
+ : hdll(NULL),hwnd(NULL)
+ , effect(NULL),pluginmain(NULL),audiomaster(NULL)
+ , responder(resp)
+ , posx(0),posy(0),caption(true)
+ , midichannel(0),eventqusz(0)
+ , paramnamecnt(0)
+ , transchg(true)
+ , playing(false),looping(false)
+ , samplerate(0)
+ , samplepos(0),ppqpos(0)
+ , tempo(120)
+ , timesignom(4),timesigden(4)
+ , barstartpos(0)
+ , cyclestartpos(0),cycleendpos(0)
+ , smpteoffset(0),smpterate(0)
{}
VSTPlugin::~VSTPlugin()
{
- Free(); // Call free
+ Free();
}
-
-void VSTPlugin::FreeVST(MHandle handle)
-{
-#if FLEXT_OS == FLEXT_OS_WIN
- FreeLibrary(handle);
-#elif FLEXT_OS == FLEXT_OS_MAC
-#else
-#error Platform not supported
-#endif
-}
+
#if FLEXT_OS == FLEXT_OS_MAC
-OSStatus FSPathMakeFSSpec(
- const UInt8 *path,
- FSSpec *spec,
- Boolean *isDirectory) /* can be NULL */
+OSStatus FSPathMakeFSSpec(const UInt8 *path,FSSpec *spec,Boolean *isDirectory) /* can be NULL */
{
- OSStatus result;
- FSRef ref;
-
- /* check parameters */
- require_action(NULL != spec, BadParameter, result = paramErr);
-
- /* convert the POSIX path to an FSRef */
- result = FSPathMakeRef(path, &ref, isDirectory);
- require_noerr(result, FSPathMakeRef);
-
- /* and then convert the FSRef to an FSSpec */
- result = FSGetCatalogInfo(&ref, kFSCatInfoNone, NULL, NULL, spec, NULL);
- require_noerr(result, FSGetCatalogInfo);
+ OSStatus result;
+ FSRef ref;
+
+ /* check parameters */
+ require_action(NULL != spec, BadParameter, result = paramErr);
+
+ /* convert the POSIX path to an FSRef */
+ result = FSPathMakeRef(path, &ref, isDirectory);
+ require_noerr(result, FSPathMakeRef);
+
+ /* and then convert the FSRef to an FSSpec */
+ result = FSGetCatalogInfo(&ref, kFSCatInfoNone, NULL, NULL, spec, NULL);
+ require_noerr(result, FSGetCatalogInfo);
FSGetCatalogInfo:
FSPathMakeRef:
BadParameter:
-
- return ( result );
+ return result;
}
#endif
-static long uniqueid = 0;
-
-int VSTPlugin::Instance(const char *dllname,const char *subname)
+// hdll, pluginmain and audiomaster are set here
+// must be NULL beforehand!
+bool VSTPlugin::NewPlugin(const char *plugname)
{
-#ifdef FLEXT_DEBUG
- flext::post("New Plugin 1 - %x",this);
-#endif
+ FLEXT_ASSERT(!hdll && !pluginmain && !audiomaster);
+
+ dllname = plugname;
- PVSTMAIN pluginmain;
#if FLEXT_OS == FLEXT_OS_WIN
- h_dll = LoadLibrary(dllname);
- if(!h_dll)
- return VSTINSTANCE_ERR_NO_VALID_FILE;
+ hdll = LoadLibrary(dllname.c_str());
+ if(hdll) pluginmain = (PVSTMAIN)GetProcAddress(hdll,"main");
+ audiomaster = Master;
- pluginmain = (PVSTMAIN)GetProcAddress(h_dll,"main");
- void *audioMasterFPtr = Master;
-
#elif FLEXT_OS == FLEXT_OS_MAC
short resFileID;
FSSpec spec;
OSErr err;
- err = FSPathMakeFSSpec(dllname,&spec,NULL);
+ err = FSPathMakeFSSpec(dllname.c_str(),&spec,NULL);
resFileID = FSpOpenResFile(&spec, fsRdPerm);
short cResCB = Count1Resources('aEff');
@@ -104,7 +123,7 @@ int VSTPlugin::Instance(const char *dllname,const char *subname)
OSType resType;
codeH = Get1IndResource('aEff', short(i+1));
- if (!codeH) continue;
+ if(!codeH) continue;
GetResInfo(codeH, &resID, &resType, fragName);
DetachResource(codeH);
@@ -116,7 +135,7 @@ int VSTPlugin::Instance(const char *dllname,const char *subname)
kPrivateCFragCopy,
&connID, (Ptr *) & mainAddr, errName);
- if (!err) {
+ if(!err) {
#ifdef __CFM__
pluginmain = (PVSTMAIN)NewMachOFromCFM(mainAddr);
#else
@@ -124,10 +143,9 @@ int VSTPlugin::Instance(const char *dllname,const char *subname)
#endif
}
}
-
CloseResFile(resFileID);
- void *audioMasterFPtr =
+ audiomaster =
#ifdef __CFM__
NewCFMFromMachO(Master);
#else
@@ -138,702 +156,190 @@ int VSTPlugin::Instance(const char *dllname,const char *subname)
#error Platform not supported
#endif
- if(!pluginmain) {
- FreeVST(h_dll);
- _pEffect = NULL;
- return VSTINSTANCE_ERR_NO_VST_PLUGIN;
- }
-
-
- uniqueid = 0;
-
- //This calls the "main" function and receives the pointer to the AEffect structure.
- _pEffect = pluginmain((audioMasterCallback)audioMasterFPtr);
- if(!_pEffect || _pEffect->magic != kEffectMagic) {
- post("VST plugin : Unable to create effect");
-
- _pEffect = NULL;
- FreeVST(h_dll);
- h_dll = NULL;
- return VSTINSTANCE_ERR_REJECTED;
- }
-
- if(subname && *subname && Dispatch(effGetPlugCategory) == kPlugCategShell) {
- // scan shell for subplugins
- char tempName[64];
- char idname[5]; idname[4] = 0;
- while((uniqueid = Dispatch(effShellGetNextPlugin,0,0,tempName))) {
- // subplug needs a name
- *(long *)idname = uniqueid;
- post("plug %s - %s",idname,tempName);
- if(!strcmp(subname,tempName) || !strcmp(subname,idname)) break;
- }
- }
-
- if(uniqueid) {
- // re-init with uniqueID set
- _pEffect = pluginmain((audioMasterCallback)audioMasterFPtr);
- if(!_pEffect || _pEffect->magic != kEffectMagic) {
- post("VST plugin : Unable to create effect");
-
- _pEffect = NULL;
- FreeVST(h_dll);
- h_dll = NULL;
- return VSTINSTANCE_ERR_REJECTED;
- }
+ if(hdll && pluginmain && audiomaster)
+ return true;
+ else {
+ FreePlugin();
+ return false;
}
+}
+void VSTPlugin::FreePlugin()
+{
+#if FLEXT_OS == FLEXT_OS_WIN
+ if(hdll) FreeLibrary(hdll);
+#elif FLEXT_OS == FLEXT_OS_MAC
+
#ifdef __MACOSX__
#ifdef __CFM__
- DisposeCFMFromMachO(audioMasterFPtr);
- DisposeMachOFromCFM(pluginmain);
-#endif
+ if(audiomaster) DisposeCFMFromMachO(audiomaster);
+ if(pluginmain) DisposeMachOFromCFM(pluginmain);
#endif
-
-
- //init plugin
- _pEffect->user = this;
-
- long ret = Dispatch( effOpen );
- FLEXT_ASSERT(!ret);
-
- ret = Dispatch( effIdentify);
- FLEXT_ASSERT(ret == 'NvEf');
-
- *_sProductName = 0;
- ret = Dispatch( effGetProductString, 0, 0, _sProductName, 0.0f);
- if(!*_sProductName) {
- // no product name given by plugin -> extract it from the filename
-
- std::string str1(dllname);
- std::string::size_type slpos = str1.rfind('\\');
- if(slpos == std::string::npos) {
- slpos = str1.rfind('/');
- if(slpos == std::string::npos)
- slpos = 0;
- else
- ++slpos;
- }
- else
- ++slpos;
- std::string str2 = str1.substr(slpos);
- int snip = str2.find('.');
- if( snip != std::string::npos )
- str1 = str2.substr(0,snip);
- else
- str1 = str2;
- strcpy(_sProductName,str1.c_str());
- }
-
- if(*_sProductName) {
- char tmp[512];
- sprintf(tmp,"vst~ - %s",_sProductName);
- title = tmp;
- }
- else
- title = "vst~";
-
- *_sVendorName = 0;
- Dispatch( effGetVendorString, 0, 0,_sVendorName, 0.0f);
-
- _sDllName = dllname;
-
-#ifdef FLEXT_DEBUG
- flext::post("New Plugin 2 - %x",this);
#endif
- return VSTINSTANCE_NO_ERROR;
-}
+#else
+#error Platform not supported
+#endif
+ effect = NULL;
+ audiomaster = NULL;
+ pluginmain = NULL;
+ hdll = NULL;
+}
/*
-void VSTPlugin::Create(VSTPlugin *plug)
-{
- h_dll = plug->h_dll;
- _pEffect = plug->_pEffect;
- _pEffect->user = this;
-
- Dispatch( effMainsChanged, 0, 1);
-// 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;
-}
+This is static to be able to communicate between the plugin methods
+and the static Audiomaster function
+the this (plugin->user) pointer has not been initialized at the point it is needed
+static should not be a problem, as we are single-threaded and it is immediately
+queried in a called function
*/
+long VSTPlugin::uniqueid = 0;
-void VSTPlugin::Free() // Called also in destruction
-{
- if(Is()) {
- if(IsEdited()) StopEditor(this);
-
- // shut down plugin
- Dispatch(effMainsChanged, 0, 0);
- Dispatch(effClose);
-
-#ifdef FLEXT_DEBUG
- flext::post("Free Plugin 1 - %x",this);
-#endif
-
- _pEffect = NULL;
-
- // \TODO
- // Here, we really have to wait until the editor thread has terminated
- // otherwise WM_DESTROY etc. messages may still be pending
- // in other words: this is a design flaw
- // There should be a data stub accessible from the plugin object and the thread
- // holding the necessary data, so that both can operate independently
-
- if(h_dll) {
- FreeVST(h_dll);
- h_dll = NULL;
- }
-
-#ifdef FLEXT_DEBUG
- flext::post("Free Plugin 2 - %x",this);
-#endif
- }
-}
-
-void VSTPlugin::DspInit(float samplerate,int blocksize)
-{
- // 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);
-}
+std::string VSTPlugin::dllloading;
-static void striptrail(char *txt)
+bool VSTPlugin::InstPlugin(long plugid)
{
- // 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;
-}
+ uniqueid = plugid;
+ dllloading = dllname;
-void VSTPlugin::GetParamName(int numparam,char *name) const
-{
- if(numparam < GetNumParams()) {
- name[0] = 0;
- Dispatch(effGetParamName,numparam,0,name,0.0f);
- striptrail(name);
- }
- else
- name[0] = 0;
-}
+ FLEXT_ASSERT(pluginmain && audiomaster);
-bool VSTPlugin::SetParamFloat(int parameter,float value)
-{
- if(Is() && parameter >= 0 && parameter < GetNumParams()) {
- _pEffect->setParameter(_pEffect,parameter,value);
- return true;
- }
- else
+ //This calls the "main" function and receives the pointer to the AEffect structure.
+ effect = pluginmain(audiomaster);
+ if(!effect || effect->magic != kEffectMagic) {
+ post("VST plugin : Unable to create effect");
+ effect = NULL;
return false;
-}
-
-void VSTPlugin::GetParamValue(int numparam,char *parval) const
-{
- if(Is()) {
- if(numparam < GetNumParams()) {
- // how many chars needed?
- char par_display[64]; par_display[0] = 0;
- Dispatch(effGetParamDisplay,numparam,0,par_display,0.0f);
-// 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
- strcpy(parval,"Index out of range");
}
- else
- strcpy(parval,"Plugin not loaded");
-}
-
-float VSTPlugin::GetParamValue(int numparam) const
-{
- if(Is() && numparam < GetNumParams())
- return _pEffect->getParameter(_pEffect, numparam);
- else
- return -1.0;
+ return true;
}
-void VSTPlugin::ScanParams(int cnt)
+bool VSTPlugin::Instance(const char *name,const char *subname)
{
- 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;
+ bool ok = effect != NULL;
+
+ if(!ok && dllname != name) {
+ FreePlugin();
+ // freshly load plugin
+ ok = NewPlugin(name) && InstPlugin();
}
- 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()) {
- if(open) {
- if(HasEditor() && !IsEdited())
- StartEditor(this);
- }
- else if(IsEdited())
- StopEditor(this);
- }
-}
+ if(ok && subname && *subname && Dispatch(effGetPlugCategory) == kPlugCategShell) {
+ // sub plugin-name given -> scan plugs
-void VSTPlugin::StartEditing(WHandle h)
-{
- FLEXT_ASSERT(h != NULL);
- Dispatch(effEditOpen,0,0,hwnd = h);
-// Dispatch(effEditTop);
-
- TitleEditor(this,title.c_str());
-}
+ long plugid;
+ char tmp[64];
+ // scan shell for subplugins
+ while((plugid = Dispatch(effShellGetNextPlugin,0,0,tmp))) {
+ // subplug needs a name
+ FLEXT_LOG1("subplug %s",tmp);
+ if(!strcmp(subname,tmp))
+ // found
+ break;
+ }
-void VSTPlugin::StopEditing()
-{
- if(Is()) {
- Dispatch(effEditClose);
- hwnd = NULL;
+ // re-init with plugid set
+ if(plugid) ok = InstPlugin(plugid);
}
-}
-
-void VSTPlugin::Visible(bool vis)
-{
- if(Is() && IsEdited()) ShowEditor(this,vis);
-}
-
-bool VSTPlugin::IsVisible() const
-{
- return Is() && IsEdited() && IsEditorShown(this);
-}
-
-bool VSTPlugin::AddMIDI(unsigned char data0,unsigned char data1,unsigned char data2)
-{
- if(Is()) {
- 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(Is() && queue_size > 0) {
- // Prepare MIDI events and free queue dispatching all events
- events.numEvents = queue_size;
- events.reserved = 0;
- for(int q = 0; q < queue_size; q++)
- events.events[q] = (VstEvent*)&midievent[q];
-
- Dispatch(effProcessEvents, 0, 0, &events, 0.0f);
- queue_size = 0;
- }
-}
-
-static int range(int value,int mn = 0,int mx = 127)
-{
- return value < mn?mn:(value > mx?mx:value);
-}
-
-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);
-}
-void VSTPlugin::AddAftertouch(int value)
-{
- AddMIDI( (char)MIDI_NOTEOFF | _midichannel , range(value) );
-}
-
-void VSTPlugin::AddPitchBend(int value)
-{
- AddMIDI( MIDI_PITCHBEND + (_midichannel & 0xf) , ((value>>7) & 127), (value & 127));
-}
-
-void VSTPlugin::AddProgramChange(int value)
-{
- AddMIDI( MIDI_PROGRAMCHANGE + (_midichannel & 0xf), range(value), 0);
-}
-
-void VSTPlugin::AddControlChange(int control, int value)
-{
- AddMIDI( MIDI_CONTROLCHANGE + (_midichannel & 0xf), range(control), range(value));
-}
-
-
-bool VSTPlugin::GetProgramName( int cat , int p, char *buf) const
-{
- buf[0] = 0;
- int parameter = p;
- if(parameter < GetNumPrograms() && cat < GetNumCategories()) {
- Dispatch(effGetProgramNameIndexed,parameter,cat,buf,0.0f);
- striptrail(buf);
- return true;
- }
- else
- return false;
-}
-
-void VSTPlugin::SetPos(int x,int y,bool upd)
-{
- if(Is()) {
- posx = x; posy = y;
- if(upd && IsEdited()) MoveEditor(this,posx,posy);
+ if(ok) {
+ //init plugin
+ effect->user = this;
+ ok = Dispatch(effOpen) == 0;
}
-}
-void VSTPlugin::SetCaption(bool c)
-{
- if(Is()) {
- caption = c;
- if(IsEdited()) CaptionEditor(this,c);
+ if(ok) {
+ ok = Dispatch(effIdentify) == 'NvEf';
}
-}
-void VSTPlugin::SetTitle(const char *t)
-{
- if(Is()) {
- title = t;
- if(IsEdited()) TitleEditor(this,t);
- }
-}
+ if(ok) {
+ *productname = 0;
+ long ret = Dispatch(effGetProductString,0,0,productname);
+
+ if(!*productname) {
+ // no product name given by plugin -> extract it from the filename
+
+ std::string str1(dllname);
+ std::string::size_type slpos = str1.rfind('\\');
+ if(slpos == std::string::npos) {
+ slpos = str1.rfind('/');
+ if(slpos == std::string::npos)
+ slpos = 0;
+ else
+ ++slpos;
+ }
+ else
+ ++slpos;
+ std::string str2 = str1.substr(slpos);
+ int snip = str2.find('.');
+ if( snip != std::string::npos )
+ str1 = str2.substr(0,snip);
+ else
+ str1 = str2;
+ strcpy(productname,str1.c_str());
+ }
+
+ if(*productname) {
+ char tmp[512];
+ sprintf(tmp,"vst~ - %s",productname);
+ title = tmp;
+ }
+ else
+ title = "vst~";
-void VSTPlugin::processReplacing( float **inputs, float **outputs, long sampleframes )
-{
- _pEffect->processReplacing( _pEffect , inputs , outputs , sampleframes );
-}
+ *vendorname = 0;
+ Dispatch(effGetVendorString,0,0,vendorname);
+ }
-void VSTPlugin::process( float **inputs, float **outputs, long sampleframes )
-{
- _pEffect->process( _pEffect , inputs , outputs , sampleframes );
+ if(!ok) Free();
+ return ok;
}
-#if 1
-
-// Host callback dispatcher
-long VSTPlugin::Master(AEffect *effect, long opcode, long index, long value, void *ptr, float opt)
+void VSTPlugin::Free() // Called also in destruction
{
-#if 0
- audioMasterEnum op = (audioMasterEnum)opcode;
- audioMasterEnumx opx = (audioMasterEnumx)opcode;
-#endif
-
-#ifdef FLEXT_DEBUG
- post("VST -> host: Eff = 0x%.8X, Opcode = %d, Index = %d, Value = %d, PTR = %.8X, OPT = %.3f\n",(int)effect, opcode,index,value,(int)ptr,opt);
-#endif
-
-// VSTPlugin *th = effect?(VSTPlugin *)effect->user:NULL;
+ if(effect) {
+ Edit(false);
- switch (opcode) {
- case audioMasterAutomate: // 0
-#ifdef FLEXT_DEBUG
- post("Automate index=%li value=%li opt=%f",index,value,opt);
-#endif
- // index, value given
- //! \todo set effect parameter
- return 0;
- case audioMasterVersion: // 1
- // support VST 2.3
- return 2300;
-// return 2;
- case audioMasterCurrentId: { // 2
- return uniqueid;
+ // shut down plugin
+ Dispatch(effMainsChanged, 0, 0);
+ Dispatch(effClose);
}
- case audioMasterIdle: // 3
- effect->dispatcher(effect, effEditIdle, 0, 0, NULL, 0.0f);
- return 0;
- case audioMasterPinConnected: // 4
- //! \todo set connection state correctly (if possible..)
- // index=pin, value=0..input, else..output
-#ifdef FLEXT_DEBUG
- post("Pin connected pin=%li conn=%li",index,value);
-#endif
- return 0; // 0 means connected
- case audioMasterWantMidi: // 6
-#ifdef FLEXT_DEBUG
- post("Want MIDI = %li",value);
-#endif
- return 0; // VST header says: "currently ignored"
- case audioMasterGetTime: // 7
- return 0; // not supported
- case audioMasterProcessEvents: { // 8
- // VST event data from plugin
- VstEvent *ev = static_cast<VstEvent *>(ptr);
- if(ev->type == kVstMidiType) {
- VstMidiEvent *mev = static_cast<VstMidiEvent *>(ptr);
-#ifdef FLEXT_DEBUG
- if(mev->byteSize == 24)
- post("MIDI event delta=%li len=%li offs=%li detune=%i offvel=%i",mev->deltaFrames,mev->noteLength,mev->noteOffset,(int)mev->detune,(int)mev->noteOffVelocity);
- else
- // has incorrect size
- post("MIDI event");
-#endif
- }
- else {
-#ifdef FLEXT_DEBUG
- post("VST event type=%li",ev->type);
-#endif
- }
- return 1;
- }
- case audioMasterSetTime: { // 9
- VstTimeInfo *tminfo = static_cast<VstTimeInfo *>(ptr);
-#ifdef FLEXT_DEBUG
- post("TimeInfo pos=%lf rate=%lf filter=%li",tminfo->samplePos,tminfo->sampleRate,value);
-#endif
- return 0; // not supported
- }
- case audioMasterTempoAt: // 10
- return 0; // not supported
- case audioMasterGetNumAutomatableParameters: // 11
- return 0; // not supported
- case audioMasterSizeWindow: // 15
- return 0;
-// case audioMasterGetSampleRate: // 16
-// case audioMasterGetBlockSize: // 17
- case audioMasterGetCurrentProcessLevel: // 23
- // return thread state
- return flext::GetThreadId() == flext::GetSysThreadId()?2:1;
- case audioMasterGetVendorString: // 32
- strcpy((char*)ptr,"grrrr.org");
- return 0;
- case audioMasterGetProductString: // 33
- strcpy((char *)ptr,"vst~ host external");
- return 0;
- case audioMasterGetVendorVersion: // 34
- return 100;
- case audioMasterCanDo: // 37
-#ifdef FLEXT_DEBUG
- post("\taudioMasterCanDo PTR = %s",ptr);
-#endif
- if(!strcmp((char *)ptr,"sendVstEvents"))
- return 1;
- else if(!strcmp((char *)ptr,"sendVstMidiEvent"))
- return 1;
- else if(!strcmp((char *)ptr,"sendVstTimeInfo"))
- return 1; // NOT YET
- else if(!strcmp((char *)ptr,"receiveVstEvents"))
- return 1;
- else if(!strcmp((char *)ptr,"receiveVstMidiEvent"))
- return 1;
- else if(!strcmp((char *)ptr,"receiveVstTimeInfo"))
- return 1; // NOT YET
- else if(!strcmp((char *)ptr,"reportConnectionChanges"))
- return 0; // \TODO PD has hard times supporting that...
- else if(!strcmp((char *)ptr,"acceptIOChanges"))
- return 0; // \TODO what does this means exactly?
- else if(!strcmp((char *)ptr,"supplyIdle"))
- return 1;
- else if(!strcmp((char *)ptr,"sizeWindow"))
- return 1;
- else if(!strcmp((char *)ptr,"supportShell"))
- return 0; // deprecated - new one is shellCategory
- else if(!strcmp((char *)ptr,"offline"))
- return 0; // not supported
- else if(!strcmp((char *)ptr,"asyncProcessing"))
- return 0; // not supported
- else if(!strcmp((char *)ptr,"shellCategory"))
- return 1; // supported!
-
- return 0; // not supported
- case audioMasterGetLanguage: // 38
- return kVstLangEnglish;
- case audioMasterGetDirectory: // 41
- // return full path of plugin
- return 0; // not supported
- case audioMasterUpdateDisplay: // 42
-#ifdef FLEXT_DEBUG
- post("UPDATE DISPLAY");
-#endif
- return 0;
- default:
-#ifdef FLEXT_DEBUG
- post("Unknown opcode %li",opcode);
-#endif
- return 0;
- }
-}
+ // \TODO
+ // Here, we really have to wait until the editor thread has terminated
+ // otherwise WM_DESTROY etc. messages may still be pending
+ // in other words: this is a design flaw
+ // There should be a data stub accessible from the plugin object and the thread
+ // holding the necessary data, so that both can operate independently
-#else
+ FreePlugin();
+}
-// Host callback dispatcher
-long VSTPlugin::Master(AEffect *effect, long opcode, long index, long value, void *ptr, float opt)
+void VSTPlugin::DspInit(float sr,int blsz)
{
- VSTPlugin *th = effect?(VSTPlugin *)effect->user:NULL;
- if(!th) FLEXT_LOG("No this");
-
-#ifdef FLEXT_DEBUG
- if(opcode != audioMasterGetTime)
- 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);
-#endif
-
- // Support opcodes
- switch(opcode)
- {
- case audioMasterAutomate:
- return 0; // index, value, returns 0
-
- case audioMasterVersion:
- return 2; // vst version, currently 7 (0 for older)
-
- case audioMasterCurrentId:
- return subplugid;
-
- 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:
- if(value == 0)
- return index < 2?0:1; //input
- else
- return index < 2?0:1; //output
-
-/*
- 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 = th?th->sample_rate:0;
- return (long)&_timeInfo;
-
-
- case audioMasterTempoAt:
- return 0;
-
- case audioMasterNeedIdle:
-// effect->dispatcher(effect, effIdle, 0, 0, NULL, 0.0f);
- return 1;
-
- case audioMasterGetSampleRate:
- return th?(long)th->sample_rate:0;
-
- 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;
+ // sample rate and block size must _first_ be set
+ Dispatch(effSetSampleRate,0,0,NULL,samplerate = sr);
+ Dispatch(effSetBlockSize, 0,blsz);
+ // then signal that mains have changed!
+ Dispatch(effMainsChanged,0,1);
+}
+
+void VSTPlugin::ListPlugs(const t_symbol *sym) const
+{
+ if(responder) {
+ if(Is() && Dispatch(effGetPlugCategory) == kPlugCategShell) {
+ t_atom at;
+ // sub plugin-name given -> scan plugs
+ char tmp[64];
+ // scan shell for subplugins
+ while(Dispatch(effShellGetNextPlugin,0,0,tmp)) {
+ SetString(at,tmp);
+ responder->Respond(sym,1,&at);
+ }
+ }
- case audioMasterGetLanguage:
- return kVstLangEnglish;
-
- case audioMasterUpdateDisplay:
- FLEXT_LOG("audioMasterUpdateDisplay");
- effect->dispatcher(effect, effEditIdle, 0, 0, NULL, 0.0f);
- return 0;
-
- case audioMasterCanDo:
- if (!strcmp((char *)ptr,"sendVstEvents")) return 1;
- else if (!strcmp((char *)ptr,"sendVstMidiEvent")) return 1;
- else if (!strcmp((char *)ptr,"sendVstTimeInfo")) return 1;
-// "receiveVstEvents",
-// "receiveVstMidiEvent",
-// "receiveVstTimeInfo",
-
-// "reportConnectionChanges",
-// "acceptIOChanges",
-// else if (!strcmp((char*)ptr,"sizeWindow")) return 1;
- else if (!strcmp((char*)ptr,"supplyIdle")) return 1;
- return -1;
-
- case audioMasterSetTime: FLEXT_LOG("VST master dispatcher: Set Time");break;
- case audioMasterGetNumAutomatableParameters: FLEXT_LOG("VST master dispatcher: GetNumAutPar");break;
- case audioMasterGetParameterQuantization: FLEXT_LOG("VST master dispatcher: ParamQuant");break;
- case audioMasterIOChanged: FLEXT_LOG("VST master dispatcher: IOchanged");break;
- case audioMasterSizeWindow: FLEXT_LOG("VST master dispatcher: Size Window");break;
- case audioMasterGetBlockSize: FLEXT_LOG("VST master dispatcher: GetBlockSize");break;
- case audioMasterGetInputLatency: FLEXT_LOG("VST master dispatcher: GetInLatency");break;
- case audioMasterGetOutputLatency: FLEXT_LOG("VST master dispatcher: GetOutLatency");break;
- case audioMasterGetPreviousPlug: FLEXT_LOG("VST master dispatcher: PrevPlug");break;
- case audioMasterGetNextPlug: FLEXT_LOG("VST master dispatcher: NextPlug");break;
- case audioMasterWillReplaceOrAccumulate: FLEXT_LOG("VST master dispatcher: WillReplace"); break;
- case audioMasterGetCurrentProcessLevel: return 0; break;
- case audioMasterGetAutomationState: FLEXT_LOG("VST master dispatcher: GetAutState");break;
- case audioMasterOfflineStart: FLEXT_LOG("VST master dispatcher: Offlinestart");break;
- case audioMasterOfflineRead: FLEXT_LOG("VST master dispatcher: Offlineread");break;
- case audioMasterOfflineWrite: FLEXT_LOG("VST master dispatcher: Offlinewrite");break;
- case audioMasterOfflineGetCurrentPass: FLEXT_LOG("VST master dispatcher: OfflineGetcurrentpass");break;
- case audioMasterOfflineGetCurrentMetaPass: FLEXT_LOG("VST master dispatcher: GetGetCurrentMetapass");break;
- case audioMasterSetOutputSampleRate: FLEXT_LOG("VST master dispatcher: Setsamplerate");break;
- case audioMasterGetSpeakerArrangement: FLEXT_LOG("VST master dispatcher: Getspeaker");break;
- case audioMasterSetIcon: FLEXT_LOG("VST master dispatcher: seticon");break;
- case audioMasterOpenWindow: FLEXT_LOG("VST master dispatcher: OpenWindow");break;
- case audioMasterCloseWindow: FLEXT_LOG("VST master dispatcher: CloseWindow");break;
- case audioMasterGetDirectory: FLEXT_LOG("VST master dispatcher: GetDirectory");break;
-// case audioMasterUpdateDisplay: post("VST master dispatcher: audioMasterUpdateDisplay");break;
-
-#ifdef FLEXT_DEBUG
- default:
- post("VST master dispatcher: undefed: %d , %d",opcode , effKeysRequired );
-#endif
- }
-
- return 0;
+ // bang
+ responder->Respond(sym);
+ }
}
-
-#endif
diff --git a/externals/grill/vst/src/vsthost.h b/externals/grill/vst/src/vsthost.h
index 185a7113..8dc20394 100644
--- a/externals/grill/vst/src/vsthost.h
+++ b/externals/grill/vst/src/vsthost.h
@@ -2,7 +2,7 @@
vst~ - VST plugin object for PD
based on the work of Jarno Seppänen and Mark Williamson
-Copyright (c)2003-2004 Thomas Grill (xovo@gmx.net)
+Copyright (c)2003-2005 Thomas Grill (gr@grrrr.org)
For information on usage and redistribution, and for a DISCLAIMER OF ALL
WARRANTIES, see the file, "license.txt," in this distribution.
*/
@@ -11,9 +11,13 @@ WARRANTIES, see the file, "license.txt," in this distribution.
#define __VSTHOST_H
#include <flext.h>
+#include <string>
+#include <map>
+#include <math.h>
+
#include "AEffectx.h"
#include "AEffEditor.hpp"
-#include <string>
+
#if FLEXT_OS == FLEXT_OS_WIN
#include <windows.h>
@@ -28,51 +32,57 @@ typedef void *MHandle;
#endif
-#define MAX_EVENTS 64
-#define MAX_INOUTS 8
-
-#define VSTINSTANCE_ERR_NO_VALID_FILE -1
-#define VSTINSTANCE_ERR_NO_VST_PLUGIN -2
-#define VSTINSTANCE_ERR_REJECTED -3
-#define VSTINSTANCE_NO_ERROR 0
-
-#define MIDI_NOTEON 144
-#define MIDI_NOTEOFF 128
-#define MIDI_POLYAFTERTOUCH 160
-#define MIDI_CONTROLCHANGE 176
-#define MIDI_PROGRAMCHANGE 192
-#define MIDI_AFTERTOUCH 208
-#define MIDI_PITCHBEND 224
+#define MIDI_MAX_EVENTS 64
+class Responder
+{
+public:
+ virtual void Respond(const t_symbol *sym,int argc = 0,const t_atom *argv = NULL) = 0;
+};
class VSTPlugin:
public flext
{
public:
- VSTPlugin();
+ static void Setup();
+
+ VSTPlugin(Responder *resp);
~VSTPlugin();
- int Instance(const char *dllname,const char *subplug = NULL);
+ bool Instance(const char *plug,const char *subplug = NULL);
void Free();
void DspInit(float samplerate,int blocksize);
- bool Is() const { return _pEffect != NULL; }
+ //////////////////////////////////////////////////////////////////////////////
+
+public:
+ bool Is() const { return effect != NULL; }
- long GetVersion() const { return _pEffect?_pEffect->version:0; }
+ long GetVersion() const { return effect?effect->version:0; }
bool IsSynth() const { return HasFlags(effFlagsIsSynth); }
bool IsReplacing() const { return HasFlags(effFlagsCanReplacing); }
bool HasEditor() const { return HasFlags(effFlagsHasEditor); }
- const char *GetName() const { return _sProductName; }
- const char *GetVendorName() const { return _sVendorName; }
- const char *GetDllName() const { return _sDllName.c_str(); }
+ const char *GetName() const { return productname; }
+ const char *GetVendorName() const { return vendorname; }
+ const char *GetDllName() const { return dllname.c_str(); }
- int GetNumInputs() const { return _pEffect?_pEffect->numInputs:0; }
- int GetNumOutputs() const { return _pEffect?_pEffect->numOutputs:0; }
+ int GetNumInputs() const { return effect?effect->numInputs:0; }
+ int GetNumOutputs() const { return effect?effect->numOutputs:0; }
- int GetNumParams() const { return _pEffect?_pEffect->numParams:0; }
+ void ListPlugs(const t_symbol *sym) const;
+
+private:
+ char productname[300];
+ char vendorname[300];
+ std::string dllname; // Contains dll name
+
+ //////////////////////////////////////////////////////////////////////////////
+
+public:
+ int GetNumParams() const { return effect?effect->numParams:0; }
void GetParamName(int numparam,char *name) const;
void GetParamValue(int numparam,char *parval) const;
float GetParamValue(int numparam) const;
@@ -89,21 +99,35 @@ public:
void SetCurrentProgram(int prg) { Dispatch(effSetProgram,0,prg); }
int GetCurrentProgram() const { return Dispatch(effGetProgram); }
- int GetNumPrograms() const { return _pEffect->numPrograms; }
+ int GetNumPrograms() const { return effect->numPrograms; }
int GetNumCategories() const { return Dispatch(effGetNumProgramCategories); }
- bool GetProgramName( int cat, int p , char* buf) const;
+ bool GetProgramName(int cat,int p,char* buf) const;
+
+private:
+ struct NameCmp:
+ std::less<std::string>
+ {
+ bool operator()(const std::string &a,const std::string &b) const { return a.compare(b) < 0; }
+ };
+
+ typedef std::map<std::string,int,NameCmp> NameMap;
+ int paramnamecnt;
+ NameMap paramnames;
+ //////////////////////////////////////////////////////////////////////////////
- bool AddMIDI(unsigned char data0,unsigned char data1=0,unsigned char data2=0);
+public:
+ void SetPos(int x,int y,bool upd = true);
+ void SetX(int x,bool upd = true) { SetPos(x,posy,upd); }
+ void SetY(int y,bool upd = true) { SetPos(posx,y,upd); }
+ int GetX() const { return posx; }
+ int GetY() const { return posy; }
+ void SetCaption(bool b);
+ bool GetCaption() const { return caption; }
+ void SetTitle(const char *t);
+ const char *GetTitle() const { return title.c_str(); }
- bool AddNoteOn( unsigned char note,unsigned char speed,unsigned char midichannel=0);
- bool AddNoteOff( unsigned char note,unsigned char midichannel=0);
-
- void AddControlChange( int control , int value );
- void AddProgramChange( int value );
- void AddPitchBend( int value );
- void AddAftertouch( int value );
void Edit(bool open);
@@ -120,64 +144,173 @@ public:
void Paint(ERect &r) const { Dispatch(effEditDraw,0,0,&r); }
- void processReplacing( float **inputs, float **outputs, long sampleframes );
- void process( float **inputs, float **outputs, long sampleframes );
+private:
+ int posx,posy; // Window position
+ bool caption; // Window border
+ std::string title; // Window title
- long Dispatch(long opCode, long index = 0, long value = 0, void *ptr = NULL, float opt = 0) const
- {
- return Is()?_pEffect->dispatcher(_pEffect, opCode, index, value, ptr, opt):0;
- }
+ //////////////////////////////////////////////////////////////////////////////
- static long VSTCALLBACK Master(AEffect *effect, long opcode, long index, long value, void *ptr, float opt);
+public:
+ enum {
+ MIDI_NOTEON = 144,
+ MIDI_NOTEOFF = 128,
+ MIDI_POLYAFTERTOUCH = 160,
+ MIDI_CONTROLCHANGE = 176,
+ MIDI_PROGRAMCHANGE = 192,
+ MIDI_AFTERTOUCH = 208,
+ MIDI_PITCHBEND = 224
+ };
+
+ bool AddMIDI(unsigned char data0,unsigned char data1 = 0,unsigned char data2 = 0);
- void SetPos(int x,int y,bool upd = true);
- void SetX(int x,bool upd = true) { SetPos(x,posy,upd); }
- void SetY(int y,bool upd = true) { SetPos(posx,y,upd); }
- int GetX() const { return posx; }
- int GetY() const { return posy; }
- void SetCaption(bool b);
- bool GetCaption() const { return caption; }
- void SetTitle(const char *t);
- const char *GetTitle() const { return title.c_str(); }
+ static int range(int value,int mn = 0,int mx = 127) { return value < mn?mn:(value > mx?mx:value); }
-protected:
+ bool AddNoteOn(unsigned char note,unsigned char speed,unsigned char midichannel = 0)
+ {
+ return AddMIDI((char)MIDI_NOTEON|midichannel,note,speed);
+ }
- MHandle h_dll;
- WHandle hwnd;
+ bool AddNoteOff(unsigned char note,unsigned char midichannel = 0)
+ {
+ return AddMIDI((char)MIDI_NOTEOFF|midichannel,note,0);
+ }
+
+ void AddControlChange(int control,int value)
+ {
+ AddMIDI(MIDI_CONTROLCHANGE+(midichannel&0xf),range(control),range(value));
+ }
+
+ void AddProgramChange(int value)
+ {
+ AddMIDI(MIDI_PROGRAMCHANGE+(midichannel&0xf),range(value),0);
+ }
- AEffect *_pEffect;
+ void AddPitchBend(int value)
+ {
+ AddMIDI(MIDI_PITCHBEND+(midichannel&0xf),((value>>7)&127),(value&127));
+ }
- static void FreeVST(MHandle handle);
+ void AddAftertouch(int value)
+ {
+ AddMIDI((char)MIDI_AFTERTOUCH|midichannel,range(value));
+ }
- inline long GetFlags() const { return _pEffect?_pEffect->flags:0; }
- inline bool HasFlags(long msk) const { return _pEffect && (_pEffect->flags&msk); }
+private:
+ void SendMidi();
- char _sProductName[300];
- char _sVendorName[300];
- std::string _sDllName; // Contains dll name
+ // static VstTimeInfo _timeInfo;
+ VstMidiEvent midievent[MIDI_MAX_EVENTS];
+ VstEvents events;
+ int eventqusz;
- struct NameCmp:
- std::less<std::string>
+ char midichannel;
+
+ //////////////////////////////////////////////////////////////////////////////
+
+public:
+
+ void SetPlaying(bool p) { if(playing != p) transchg = true,playing = p; }
+ bool GetPlaying() const { return playing; }
+ void SetLooping(bool p) { if(looping != p) transchg = true,looping = p; }
+ bool GetLooping() const { return looping; }
+
+ void SetSamplePos(double p) { if(samplepos != p) transchg = true,samplepos = p; }
+ double GetSamplePos() const { return samplepos; }
+ void SetTempo(double p) { if(tempo != p) transchg = true,tempo = p; }
+ double GetTempo() const { return tempo; }
+ void SetPPQPos(double p) { if(ppqpos != p) transchg = true,ppqpos = p; }
+ double GetPPQPos() const { return ppqpos; }
+
+ void SetTimesigNom(int p) { if(timesignom != p) transchg = true,timesignom = p; }
+ int GetTimesigNom() const { return timesignom; }
+ void SetTimesigDen(int p) { if(timesigden != p) transchg = true,timesigden = p; }
+ int GetTimesigDen() const { return timesigden; }
+ void SetBarStart(double p) { if(barstartpos != p) transchg = true,barstartpos = p; }
+ double GetBarStart() const { return barstartpos; }
+ void SetCycleStart(double p) { if(cyclestartpos != p) transchg = true,cyclestartpos = p; }
+ double GetCycleStart() const { return cyclestartpos; }
+ void SetCycleEnd(double p) { if(cycleendpos != p) transchg = true,cycleendpos = p; }
+ double GetCycleEnd() const { return cycleendpos; }
+
+ void SetSmpteOffset(int p) { if(smpteoffset != p) transchg = true,smpteoffset = p; }
+ int GetSmpteOffset() const { return smpteoffset; }
+ void SetSmpteRate(int p) { if(smpterate != p) transchg = true,smpterate = p; }
+ int GetSmpteRate() const { return smpterate; }
+
+private:
+
+ bool playing,looping;
+ float samplerate;
+ bool transchg;
+
+ double samplepos,tempo;
+ double ppqpos;
+
+ int timesignom,timesigden;
+ double barstartpos;
+ double cyclestartpos,cycleendpos;
+ int smpteoffset,smpterate;
+
+ //////////////////////////////////////////////////////////////////////////////
+
+public:
+ void processReplacing(float **inputs,float **outputs,long sampleframes )
{
- bool operator()(const std::string &a,const std::string &b) const { return a.compare(b) < 0; }
- };
+ FLEXT_ASSERT(effect);
+ effect->processReplacing(effect,inputs,outputs,sampleframes);
+ if(playing) updatepos(sampleframes);
+ }
- typedef std::map<std::string,int,NameCmp> NameMap;
- int paramnamecnt;
- NameMap paramnames;
-
+ void process(float **inputs,float **outputs,long sampleframes )
+ {
+ FLEXT_ASSERT(effect);
+ effect->process(effect,inputs,outputs,sampleframes);
+ if(playing) updatepos(sampleframes);
+ }
-// static VstTimeInfo _timeInfo;
- VstMidiEvent midievent[MAX_EVENTS];
- VstEvents events;
- int queue_size;
+private:
+ void updatepos(long frames);
- void SendMidi();
- char _midichannel;
+ //////////////////////////////////////////////////////////////////////////////
- int posx,posy; // Window position
- bool caption; // Window border
- std::string title; // Window title
+private:
+ Responder *responder;
+
+ bool NewPlugin(const char *plugname);
+ void FreePlugin();
+ bool InstPlugin(long plugid = 0);
+
+ static long uniqueid;
+ static std::string dllloading;
+
+ inline long GetFlags() const { return effect?effect->flags:0; }
+ inline bool HasFlags(long msk) const { return effect && (effect->flags&msk); }
+
+
+ // the handle to the shared library
+ MHandle hdll;
+ // the handle to the plugin editor window
+ WHandle hwnd;
+ // the VST plugin instance
+ AEffect *effect;
+
+ typedef AEffect *(VSTCALLBACK *PVSTMAIN)(audioMasterCallback audioMaster);
+ PVSTMAIN pluginmain;
+ audioMasterCallback audiomaster;
+
+ long Dispatch(long opCode,long index = 0,long value = 0,void *ptr = NULL,float opt = 0) const
+ {
+ FLEXT_ASSERT(effect);
+ return effect->dispatcher(effect,opCode,index,value,ptr,opt);
+ }
+
+ static long VSTCALLBACK Master(AEffect *effect, long opcode, long index, long value, void *ptr, float opt);
+
+ static const t_symbol *sym_event,*sym_evmidi,*sym_evaudio,*sym_evvideo,*sym_evparam,*sym_evtrigger,*sym_evsysex,*sym_ev_;
+ static const t_symbol *sym_midi[8];
+
+ void ProcessEvent(const VstEvent &ev);
};
#endif
diff --git a/externals/grill/vst/src/vstmaster.cpp b/externals/grill/vst/src/vstmaster.cpp
new file mode 100644
index 00000000..0395fb65
--- /dev/null
+++ b/externals/grill/vst/src/vstmaster.cpp
@@ -0,0 +1,288 @@
+/*
+vst~ - VST plugin object for PD
+based on the work of Jarno Seppänen and Mark Williamson
+
+Copyright (c)2003-2005 Thomas Grill (gr@grrrr.org)
+For information on usage and redistribution, and for a DISCLAIMER OF ALL
+WARRANTIES, see the file, "license.txt," in this distribution.
+*/
+
+#include "vsthost.h"
+
+static const int VST_VERSION = 100;
+static const char *vendor = "grrrr.org";
+static const char *product = "vst~";
+
+
+void VSTPlugin::ProcessEvent(const VstEvent &ev)
+{
+ if(!responder) return;
+
+ if(ev.type == kVstMidiType) {
+ const VstMidiEvent &mev = (const VstMidiEvent &)ev;
+ t_atom lst[10];
+ SetSymbol(lst[0],sym_evmidi);
+ int midi = ((unsigned char)mev.midiData[0]>>4)-8;
+ FLEXT_ASSERT(midi >= 0 && midi < 8);
+ SetSymbol(lst[1],sym_midi[midi]);
+ SetInt(lst[2],(unsigned char)mev.midiData[0]&0x0f);
+ SetInt(lst[3],(unsigned char)mev.midiData[1]);
+ SetInt(lst[4],(unsigned char)mev.midiData[2]);
+ // what about running status? (obviously not possible)
+ SetInt(lst[5],mev.deltaFrames);
+ SetInt(lst[6],mev.noteLength);
+ SetInt(lst[7],mev.noteOffset);
+ SetInt(lst[8],(int)mev.detune);
+ SetInt(lst[9],(int)mev.noteOffVelocity);
+ responder->Respond(sym_event,9,lst);
+ }
+ else {
+ const t_symbol *sym;
+ if(ev.type == kVstAudioType)
+ sym = sym_evaudio;
+ else if(ev.type == kVstVideoType)
+ sym = sym_evvideo;
+ else if(ev.type == kVstParameterType)
+ sym = sym_evparam;
+ else if(ev.type == kVstTriggerType)
+ sym = sym_evtrigger;
+ else if(ev.type == kVstSysExType)
+ sym = sym_evsysex;
+ else
+ sym = sym_ev_;
+
+ int data = ev.byteSize-sizeof(ev.deltaFrames)-sizeof(ev.flags);
+ const int stsize = 16;
+ t_atom stlst[stsize];
+ t_atom *lst = data+3 > stsize?new t_atom[data+3]:stlst;
+
+ SetSymbol(lst[0],sym);
+ SetInt(lst[1],ev.deltaFrames);
+ SetInt(lst[2],ev.flags);
+ for(int i = 0; i < data; ++i) SetInt(lst[3],(unsigned char)ev.data[i]);
+
+ responder->Respond(sym_event,data+3,lst);
+
+ if(lst != stlst) delete[] lst;
+ }
+}
+
+// Host callback dispatcher
+long VSTPlugin::Master(AEffect *effect, long opcode, long index, long value, void *ptr, float opt)
+{
+#ifdef FLEXT_LOGGING
+ post("VST -> host: Eff = 0x%.8X, Opcode = %d, Index = %d, Value = %d, PTR = %.8X, OPT = %.3f\n",(int)effect, opcode,index,value,(int)ptr,opt);
+#endif
+
+ VSTPlugin *th = effect?(VSTPlugin *)effect->user:NULL;
+
+ switch (opcode) {
+ case audioMasterAutomate: // 0
+#ifdef FLEXT_LOGGING
+ post("Automate index=%li value=%li opt=%f",index,value,opt);
+#endif
+ // index, value given
+ //! \todo set effect parameter
+ return 0;
+
+ case audioMasterVersion: // 1
+ // support VST 2.3
+ return 2300;
+
+ case audioMasterCurrentId: // 2
+ // set to subplugin id (default 0)
+ return uniqueid;
+
+ case audioMasterIdle: // 3
+ effect->dispatcher(effect, effEditIdle, 0, 0, NULL, 0.0f);
+ return 0;
+
+ case audioMasterPinConnected: // 4
+ //! \todo set connection state correctly (if possible..)
+ // index=pin, value=0..input, else..output
+#ifdef FLEXT_LOGGING
+ post("Pin connected pin=%li conn=%li",index,value);
+#endif
+ return 0; // 0 means connected
+
+ case audioMasterWantMidi: // 6
+#ifdef FLEXT_LOGGING
+ post("Want MIDI = %li",value);
+#endif
+ return 0; // VST header says: "currently ignored"
+
+ case audioMasterGetTime: { // 7
+ if(!th) return 0;
+
+ static VstTimeInfo time;
+ memset(&time,0,sizeof(time));
+
+ // flags
+ time.flags = kVstTempoValid|kVstBarsValid|kVstCyclePosValid|kVstPpqPosValid|kVstSmpteValid|kVstTimeSigValid;
+
+ if(th->transchg) { time.flags |= kVstTransportChanged; th->transchg = false; }
+ if(th->playing) time.flags |= kVstTransportPlaying;
+ if(th->looping) time.flags |= kVstTransportCycleActive;
+
+ time.sampleRate = th->samplerate;
+ time.samplePos = th->samplepos;
+ time.ppqPos = th->ppqpos;
+
+ time.tempo = th->tempo;
+ time.barStartPos = th->barstartpos;
+ time.cycleStartPos = th->cyclestartpos;
+ time.cycleEndPos = th->cycleendpos;
+
+ time.timeSigNumerator = th->timesignom;
+ time.timeSigDenominator = th->timesigden;
+
+ // SMPTE data
+ time.smpteOffset = th->smpteoffset;
+ time.smpteFrameRate = th->smpterate;
+
+// time.samplesToNextClock = 0;
+
+ if(value&kVstNanosValid) {
+ time.nanoSeconds = flext::GetOSTime()*1.e9;
+ time.flags |= kVstNanosValid;
+ }
+
+ return (long)&time;
+ }
+
+ case audioMasterProcessEvents: { // 8
+ // VST event data from plugin
+ VstEvents *evs = static_cast<VstEvents *>(ptr);
+ if(th) {
+ for(int i = 0; i < evs->numEvents; ++i)
+ th->ProcessEvent(*evs->events[i]);
+ return 1;
+ }
+ else
+ return 0;
+ }
+
+ case audioMasterSetTime: { // 9
+ VstTimeInfo *tminfo = static_cast<VstTimeInfo *>(ptr);
+#ifdef FLEXT_DEBUG
+ post("TimeInfo pos=%lf rate=%lf filter=%li",tminfo->samplePos,tminfo->sampleRate,value);
+#endif
+ return 0; // not supported
+ }
+
+ case audioMasterTempoAt: // 10
+ return 0; // not supported
+
+ case audioMasterGetNumAutomatableParameters: // 11
+ return 0; // not supported
+
+ case audioMasterSizeWindow: // 15
+ return 0;
+
+ case audioMasterGetSampleRate: // 16
+ return 0; // not supported
+ case audioMasterGetBlockSize: // 17
+ return 0; // not supported
+
+ case audioMasterGetCurrentProcessLevel: // 23
+ // return thread state
+ return flext::GetThreadId() == flext::GetSysThreadId()?2:1;
+
+ case audioMasterGetVendorString: // 32
+ strcpy((char*)ptr,vendor);
+ return 0;
+
+ case audioMasterGetProductString: // 33
+ strcpy((char *)ptr,product);
+ return 0;
+
+ case audioMasterGetVendorVersion: // 34
+ return VST_VERSION;
+
+ case audioMasterCanDo: // 37
+#ifdef FLEXT_LOGGING
+ post("\taudioMasterCanDo PTR = %s",ptr);
+#endif
+ if(!strcmp((char *)ptr,"sendVstEvents"))
+ return 1;
+ else if(!strcmp((char *)ptr,"sendVstMidiEvent"))
+ return 1;
+ else if(!strcmp((char *)ptr,"sendVstTimeInfo"))
+ return 1; // NOT YET
+ else if(!strcmp((char *)ptr,"receiveVstEvents"))
+ return 1;
+ else if(!strcmp((char *)ptr,"receiveVstMidiEvent"))
+ return 1;
+ else if(!strcmp((char *)ptr,"receiveVstTimeInfo"))
+ return 1; // NOT YET
+ else if(!strcmp((char *)ptr,"reportConnectionChanges"))
+ return 0; // \TODO PD has hard times supporting that...
+ else if(!strcmp((char *)ptr,"acceptIOChanges"))
+ return 0; // \TODO what does this means exactly?
+ else if(!strcmp((char *)ptr,"supplyIdle"))
+ return 1;
+ else if(!strcmp((char *)ptr,"sizeWindow"))
+ return 1;
+ else if(!strcmp((char *)ptr,"supportShell"))
+ return 0; // deprecated - new one is shellCategory
+ else if(!strcmp((char *)ptr,"offline"))
+ return 0; // not supported
+ else if(!strcmp((char *)ptr,"asyncProcessing"))
+ return 0; // not supported
+ else if(!strcmp((char *)ptr,"shellCategory"))
+ return 1; // supported!
+ else if(!strcmp((char *)ptr,"editFile"))
+ return 0; // not supported
+ else if(!strcmp((char *)ptr,"openFileSelector"))
+ return 0; // not supported
+ else if(!strcmp((char *)ptr,"closeFileSelector"))
+ return 0; // not supported
+ else if(!strcmp((char *)ptr,"startStopProcess"))
+ return 0; // not supported
+#ifdef FLEXT_DEBUG
+ else
+ post("Unknown audioMasterCanDo PTR = %s",ptr);
+#endif
+
+ return 0; // not supported
+
+ case audioMasterGetLanguage: // 38
+ return kVstLangEnglish;
+
+ case audioMasterGetDirectory: // 41
+ return (long)(th?th->dllname.c_str():dllloading.c_str());
+
+ case audioMasterUpdateDisplay: // 42
+#ifdef FLEXT_LOGGING
+ post("UPDATE DISPLAY");
+#endif
+ return 0;
+
+ default:
+#ifdef FLEXT_DEBUG
+ post("Unknown opcode %li",opcode);
+#endif
+ return 0;
+ }
+}
+
+void VSTPlugin::updatepos(long frames)
+{
+ bool inloop = ppqpos < cycleendpos;
+
+ // \todo should the sample position also jump back when cycling?
+ // and if, how?
+ samplepos += frames;
+
+ ppqpos += frames*tempo/(samplerate*60);
+
+ if(looping) {
+ double cyclelen = cycleendpos-cyclestartpos;
+ if(cyclelen > 0) {
+ if(inloop && ppqpos >= cycleendpos)
+ ppqpos = cyclestartpos+fmod(ppqpos-cyclestartpos,cyclelen);
+ }
+ else
+ ppqpos = cyclestartpos;
+ }
+}
diff --git a/externals/grill/vst/src/vstmidi.cpp b/externals/grill/vst/src/vstmidi.cpp
new file mode 100644
index 00000000..8bddba98
--- /dev/null
+++ b/externals/grill/vst/src/vstmidi.cpp
@@ -0,0 +1,52 @@
+/*
+vst~ - VST plugin object for PD
+based on the work of Jarno Seppänen and Mark Williamson
+
+Copyright (c)2003-2005 Thomas Grill (gr@grrrr.org)
+For information on usage and redistribution, and for a DISCLAIMER OF ALL
+WARRANTIES, see the file, "license.txt," in this distribution.
+*/
+
+#include "vsthost.h"
+
+bool VSTPlugin::AddMIDI(unsigned char data0,unsigned char data1,unsigned char data2)
+{
+ if(Is()) {
+ VstMidiEvent *pevent = &midievent[eventqusz];
+
+ 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(eventqusz < MIDI_MAX_EVENTS) ++eventqusz;
+ SendMidi();
+ return true;
+ }
+ else return false;
+}
+
+
+void VSTPlugin::SendMidi()
+{
+ if(Is() && eventqusz > 0) {
+ // Prepare MIDI events and free queue dispatching all events
+ events.numEvents = eventqusz;
+ events.reserved = 0;
+ for(int q = 0; q < eventqusz; q++)
+ events.events[q] = (VstEvent*)&midievent[q];
+
+ Dispatch(effProcessEvents, 0, 0, &events, 0.0f);
+ eventqusz = 0;
+ }
+}
diff --git a/externals/grill/vst/src/vstparam.cpp b/externals/grill/vst/src/vstparam.cpp
new file mode 100644
index 00000000..30515b23
--- /dev/null
+++ b/externals/grill/vst/src/vstparam.cpp
@@ -0,0 +1,105 @@
+/*
+vst~ - VST plugin object for PD
+based on the work of Jarno Seppänen and Mark Williamson
+
+Copyright (c)2003-2005 Thomas Grill (gr@grrrr.org)
+For information on usage and redistribution, and for a DISCLAIMER OF ALL
+WARRANTIES, see the file, "license.txt," in this distribution.
+*/
+
+#include "vsthost.h"
+#include <ctype.h>
+
+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()) {
+ name[0] = 0;
+ Dispatch(effGetParamName,numparam,0,name);
+ striptrail(name);
+ }
+ else
+ name[0] = 0;
+}
+
+bool VSTPlugin::SetParamFloat(int parameter,float value)
+{
+ if(Is() && parameter >= 0 && parameter < GetNumParams()) {
+ effect->setParameter(effect,parameter,value);
+ return true;
+ }
+ else
+ return false;
+}
+
+void VSTPlugin::GetParamValue(int numparam,char *parval) const
+{
+ if(Is()) {
+ if(numparam < GetNumParams()) {
+ // how many chars needed?
+ char par_display[64]; par_display[0] = 0;
+ Dispatch(effGetParamDisplay,numparam,0,par_display);
+// 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);
+ striptrail(par_label);
+// if(par_label[7]) par_label[8] = 0; // set trailing zero
+
+ sprintf(parval,"%s%s",par_display,par_label);
+ }
+ else
+ strcpy(parval,"Index out of range");
+ }
+ else
+ strcpy(parval,"Plugin not loaded");
+}
+
+float VSTPlugin::GetParamValue(int numparam) const
+{
+ if(Is() && numparam < GetNumParams())
+ return effect->getParameter(effect,numparam);
+ else
+ 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;
+}
+
+bool VSTPlugin::GetProgramName(int cat,int p,char *buf) const
+{
+ buf[0] = 0;
+ int parameter = p;
+ if(parameter < GetNumPrograms() && cat < GetNumCategories()) {
+ Dispatch(effGetProgramNameIndexed,parameter,cat,buf);
+ striptrail(buf);
+ return true;
+ }
+ else
+ return false;
+}
diff --git a/externals/grill/vst/vst.vcproj b/externals/grill/vst/vst.vcproj
index 4541b83d..7121d85e 100644
--- a/externals/grill/vst/vst.vcproj
+++ b/externals/grill/vst/vst.vcproj
@@ -87,7 +87,7 @@
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories="&quot;c:\data\prog\pd\pd-cvs\src&quot;;..\flext\source;c:\data\prog\audio\vstsdk2.3\source\common"
- PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_WIN32_WINNT=0x0501,WINVER=0x0501;_USRDLL;FLEXT_SYS=2;FLEXT_THREADS;FLEXT_LOGGING"
+ PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_WIN32_WINNT=0x0501;WINVER=0x0501;_USRDLL;FLEXT_SYS=2;FLEXT_THREADS;xFLEXT_LOGGING"
BasicRuntimeChecks="3"
RuntimeLibrary="1"
UsePrecompiledHeader="2"
@@ -275,11 +275,23 @@
</FileConfiguration>
</File>
<File
+ RelativePath=".\src\vstedit.cpp">
+ </File>
+ <File
RelativePath=".\src\vsthost.cpp">
</File>
<File
RelativePath=".\src\vsthost.h">
</File>
+ <File
+ RelativePath=".\src\vstmaster.cpp">
+ </File>
+ <File
+ RelativePath=".\src\vstmidi.cpp">
+ </File>
+ <File
+ RelativePath=".\src\vstparam.cpp">
+ </File>
</Filter>
<Filter
Name="doc"
@@ -326,6 +338,9 @@
<File
RelativePath="src\main.h">
</File>
+ <File
+ RelativePath=".\src\resource.h">
+ </File>
</Files>
<Globals>
</Globals>