aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Grill <xovo@users.sourceforge.net>2005-03-11 04:58:01 +0000
committerThomas Grill <xovo@users.sourceforge.net>2005-03-11 04:58:01 +0000
commit27da08004c5f024a0f35e3cb4c2b3942548ebcfa (patch)
treec89092a5e8d13c11719b7975b9557efbf3ca131f
parent467591c8ba03dbd60ceada93482460de3b888838 (diff)
restructured VSThost code
better shell support fix for build system update for flext build systemcleanups VSTTime info added event processing (like Midi in) svn path=/trunk/; revision=2617
-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>