diff options
-rw-r--r-- | externals/grill/vst/pd/help-vst~.pd | 40 | ||||
-rw-r--r-- | externals/grill/vst/readme.txt | 8 | ||||
-rw-r--r-- | externals/grill/vst/src/Editor.h | 2 | ||||
-rw-r--r-- | externals/grill/vst/src/EditorWin.cpp | 122 | ||||
-rw-r--r-- | externals/grill/vst/src/VstHost.cpp | 61 | ||||
-rw-r--r-- | externals/grill/vst/src/VstHost.h | 8 | ||||
-rw-r--r-- | externals/grill/vst/src/main.cpp | 14 |
7 files changed, 199 insertions, 56 deletions
diff --git a/externals/grill/vst/pd/help-vst~.pd b/externals/grill/vst/pd/help-vst~.pd index f546d7a8..01e7db6b 100644 --- a/externals/grill/vst/pd/help-vst~.pd +++ b/externals/grill/vst/pd/help-vst~.pd @@ -1,4 +1,4 @@ -#N canvas 130 41 801 527 12;
+#N canvas 146 124 817 543 12;
#X obj 26 190 dac~;
#X obj 26 94 noise~;
#X obj 140 192 print A;
@@ -64,25 +64,39 @@ ;
#X text 137 173 attribute outlet;
#X text 103 137 inlets outlets [plugname];
-#N canvas 367 122 477 226 win 0;
-#X obj 34 160 s \$0-vst;
-#X msg 26 109 getx;
-#X text 155 110 get window coordinates;
-#X msg 71 109 gety;
-#X obj 23 51 nbx 5 14 -1e+037 1e+037 0 0 empty empty empty 0 -6 0 10
+#N canvas 367 122 513 321 win 0;
+#X obj 11 287 s \$0-vst;
+#X msg 28 84 getx;
+#X text 135 77 get window coordinates;
+#X msg 73 84 gety;
+#X obj 25 26 nbx 5 14 -1e+037 1e+037 0 0 empty empty empty 0 -6 0 10
-225271 -1 -1 0 256;
-#X msg 24 69 x \$1;
-#X obj 93 51 nbx 5 14 -1e+037 1e+037 0 0 empty empty empty 0 -6 0 10
+#X msg 26 44 x \$1;
+#X obj 95 26 nbx 5 14 -1e+037 1e+037 0 0 empty empty empty 0 -6 0 10
-225271 -1 -1 0 256;
-#X msg 94 67 y \$1;
-#X text 154 61 set window coordinates;
-#X text 10 7 NOT IMPLEMENTED;
+#X msg 96 42 y \$1;
+#X text 165 26 set window coordinates;
+#X text 161 43 (position of the actual VST interface);
+#X text 132 92 (position of the actual VST interface);
+#X obj 67 130 tgl 15 0 empty empty empty 0 -6 0 8 -225271 -1 -1 0 1
+;
+#X msg 66 149 caption \$1;
+#X msg 161 149 getcaption;
+#X text 69 173 set/get window caption and borders;
+#X text 68 238 set/get window title;
+#X msg 168 214 gettitle;
+#X msg 65 214 title KARL;
#X connect 1 0 0 0;
#X connect 3 0 0 0;
#X connect 4 0 5 0;
#X connect 5 0 0 0;
#X connect 6 0 7 0;
#X connect 7 0 0 0;
+#X connect 11 0 12 0;
+#X connect 12 0 0 0;
+#X connect 13 0 0 0;
+#X connect 16 0 0 0;
+#X connect 17 0 0 0;
#X restore 446 244 pd win;
#X text 512 244 manipulating the edit window;
#X msg 28 296 plug \$1;
@@ -212,6 +226,8 @@ #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 connect 1 0 30 0;
#X connect 3 0 4 0;
#X connect 4 0 12 0;
diff --git a/externals/grill/vst/readme.txt b/externals/grill/vst/readme.txt index 68917404..5702eee4 100644 --- a/externals/grill/vst/readme.txt +++ b/externals/grill/vst/readme.txt @@ -54,14 +54,14 @@ Version history: --------------------------------------------------------------------------- -features: -- allow various window styles and window moving & titling -- include necessary Steinberg license stuff - BUGS: - Waveshell crashes on load - mouse interaction in editor can cause audio dropouts +- crash when unloading plugin with open window TODO: +- add VSTTimeInfo functionality +- add Midi out functionality +- include necessary Steinberg license stuff - do name scanning in the background - translate special characters in strings (like ° as param_label) into system-digestible form diff --git a/externals/grill/vst/src/Editor.h b/externals/grill/vst/src/Editor.h index e3f9a3d6..ad03f59c 100644 --- a/externals/grill/vst/src/Editor.h +++ b/externals/grill/vst/src/Editor.h @@ -18,6 +18,8 @@ void StopEditor(VSTPlugin *p); void ShowEditor(VSTPlugin *p,bool show); void MoveEditor(VSTPlugin *p,int x,int y); void SizeEditor(VSTPlugin *p,int x,int y); +void TitleEditor(VSTPlugin *p,const char *t); +void CaptionEditor(VSTPlugin *p,bool c); bool IsEditorShown(const VSTPlugin *p); #endif // __EDITOR_H diff --git a/externals/grill/vst/src/EditorWin.cpp b/externals/grill/vst/src/EditorWin.cpp index 9a79c391..82ab55ba 100644 --- a/externals/grill/vst/src/EditorWin.cpp +++ b/externals/grill/vst/src/EditorWin.cpp @@ -35,18 +35,24 @@ static LRESULT CALLBACK wndproc(HWND hwnd,UINT msg,WPARAM wp,LPARAM lp) LRESULT res = 0; -// post("Message %x",msg); switch(msg) { -// case WM_NCREATE: res = TRUE; break; case WM_CREATE: // Initialize the window. plug->StartEditing(hwnd); break; case WM_CLOSE: - plug->StopEditing(); +#ifdef FLEXT_DEBUG + flext::post("WM_CLOSE"); +#endif + // plug could already have been unloaded... + plug->StopEditing(); // this sets plug->hwnd = NULL DestroyWindow(hwnd); break; case WM_DESTROY: +#ifdef FLEXT_DEBUG + flext::post("WM_DESTROY"); +#endif + // stop editor thread PostQuitMessage(0); break; case WM_TIMER: @@ -56,8 +62,16 @@ static LRESULT CALLBACK wndproc(HWND hwnd,UINT msg,WPARAM wp,LPARAM lp) plug->EditorIdle(); break; case WM_MOVE: { - WORD x = LOWORD(lp),y = HIWORD(lp); - plug->SetPos(reinterpret_cast<short &>(x),reinterpret_cast<short &>(y),false); + // ignore after WM_CLOSE so that x,y positions are preserved + if(!plug->IsEdited()) break; + + WORD wx = LOWORD(lp),wy = HIWORD(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 + flext::post("WM_MOVE x/y=%i/%i",x,y); +#endif break; } /* @@ -69,17 +83,40 @@ static LRESULT CALLBACK wndproc(HWND hwnd,UINT msg,WPARAM wp,LPARAM lp) break; } */ -/* - case WM_SIZE: - // Set the size and position of the window. +#if 0 //def FLEXT_DEBUG + case WM_SIZE: { + WORD wx = LOWORD(lp),wy = HIWORD(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) + flext::post("WM_SIZE x/y=%i/%i",x,y); break; -*/ + } +#endif + default: res = DefWindowProc(hwnd,msg,wp,lp); } return res; } +static void windowsize(HWND wnd,int x,int y,int w,int h,bool caption,LONG flags = 0) +{ + WINDOWINFO winfo; + winfo.cbSize = sizeof(winfo); + GetWindowInfo(wnd,&winfo); + + int cy = caption?GetSystemMetrics(SM_CYCAPTION):0; + + SetWindowPos(wnd,HWND_TOP, + x-(winfo.rcClient.left-winfo.rcWindow.left), + y-(winfo.rcClient.top-winfo.rcWindow.top), + w+winfo.cxWindowBorders*2, + h+cy+winfo.cyWindowBorders*2, + flags + ); + +} + static void threadfun(flext::thr_params *p) { flext::RelPriority(-2); @@ -98,7 +135,7 @@ static void threadfun(flext::thr_params *p) HWND wnd = CreateWindow( WCLNAME,tmp, - WS_BORDER|WS_CAPTION|/*WS_THICKFRAME|*/WS_POPUP|WS_SYSMENU|WS_MINIMIZEBOX, + (plug->GetCaption()?WS_BORDER|WS_CAPTION:0)|WS_POPUP|WS_SYSMENU|WS_MINIMIZEBOX, CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT, NULL,NULL, hinstance,NULL @@ -121,24 +158,13 @@ static void threadfun(flext::thr_params *p) SetTimer(wnd,0,TIMER_INTERVAL,NULL); - WINDOWINFO winfo; - winfo.cbSize = sizeof(winfo); - GetWindowInfo(wnd,&winfo); - TITLEBARINFO tinfo; - tinfo.cbSize = sizeof(tinfo); - GetTitleBarInfo(wnd,&tinfo); - ERect r; plug->GetEditorRect(r); - SetWindowPos(wnd,HWND_TOP, - r.left, - r.top, - (r.right-r.left)+winfo.cxWindowBorders*2, - (r.bottom-r.top)+(tinfo.rcTitleBar.bottom-tinfo.rcTitleBar.top)+winfo.cyWindowBorders*2, - SWP_SHOWWINDOW - ); - - + windowsize(wnd,plug->GetX(),plug->GetY(),r.right-r.left,r.bottom-r.top,plug->GetCaption(),SWP_SHOWWINDOW); +#ifdef FLEXT_DEBUG + flext::post("Editor rect left/top=%i/%i, right/bottom=%i/%i",r.left,r.top,r.right,r.bottom); +#endif + // SetFocus(); // Message pump @@ -186,13 +212,25 @@ void SetupEditor() void StartEditor(VSTPlugin *p) { +#ifdef FLEXT_DEBUG + flext::post("Start editor 1"); +#endif flext::LaunchThread(threadfun,reinterpret_cast<flext::thr_params *>(p)); +#ifdef FLEXT_DEBUG + flext::post("Start editor 2"); +#endif } void StopEditor(VSTPlugin *p) { +#ifdef FLEXT_DEBUG + 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 + flext::post("Stop editor 2"); +#endif } void ShowEditor(VSTPlugin *p,bool show) @@ -202,8 +240,17 @@ void ShowEditor(VSTPlugin *p,bool show) void MoveEditor(VSTPlugin *p,int x,int y) { - // the client region must be taken into account -// SetWindowPos(p->EditorHandle(),NULL,x,y,0,0,SWP_NOSIZE|SWP_NOZORDER); + HWND wnd = p->EditorHandle(); + + WINDOWINFO winfo; + winfo.cbSize = sizeof(winfo); + GetWindowInfo(wnd,&winfo); + + SetWindowPos(wnd,NULL, + x-(winfo.rcClient.left-winfo.rcWindow.left),y-(winfo.rcClient.top-winfo.rcWindow.top), + 0,0, + SWP_NOSIZE|SWP_NOZORDER + ); } void SizeEditor(VSTPlugin *p,int x,int y) @@ -211,6 +258,25 @@ void SizeEditor(VSTPlugin *p,int x,int y) SetWindowPos(p->EditorHandle(),NULL,0,0,x,y,SWP_NOMOVE|SWP_NOZORDER); } +void CaptionEditor(VSTPlugin *plug,bool c) +{ + HWND wnd = plug->EditorHandle(); + LONG ns,style = GetWindowLong(wnd,GWL_STYLE); + if(c) ns = style|WS_BORDER|WS_CAPTION; + else ns = style&~(WS_BORDER|WS_CAPTION); + if(ns != style) { + SetWindowLong(wnd,GWL_STYLE,ns); + + ERect r; plug->GetEditorRect(r); + windowsize(wnd,plug->GetX(),plug->GetY(),r.right-r.left,r.bottom-r.top,c,SWP_FRAMECHANGED); + } +} + +void TitleEditor(VSTPlugin *p,const char *t) +{ + SetWindowText(p->EditorHandle(),t); +} + bool IsEditorShown(const VSTPlugin *p) { return IsWindowVisible(p->EditorHandle()) != FALSE; diff --git a/externals/grill/vst/src/VstHost.cpp b/externals/grill/vst/src/VstHost.cpp index bd686716..30b8ba36 100644 --- a/externals/grill/vst/src/VstHost.cpp +++ b/externals/grill/vst/src/VstHost.cpp @@ -13,14 +13,12 @@ WARRANTIES, see the file, "license.txt," in this distribution. #include <ctype.h> -static VstTimeInfo _timeInfo; - typedef AEffect *(VSTCALLBACK *PVSTMAIN)(audioMasterCallback audioMaster); VSTPlugin::VSTPlugin(): h_dll(NULL),hwnd(NULL),_pEffect(NULL), - posx(0),posy(0), + posx(0),posy(0),caption(true), _midichannel(0),queue_size(0), paramnamecnt(0) {} @@ -32,7 +30,11 @@ VSTPlugin::~VSTPlugin() int VSTPlugin::Instance(const char *dllname) { - h_dll = LoadLibrary(dllname); +#ifdef FLEXT_DEBUG + flext::post("New Plugin 1 - %x",this); +#endif + + h_dll = LoadLibrary(dllname); if(!h_dll) return VSTINSTANCE_ERR_NO_VALID_FILE; @@ -88,11 +90,23 @@ int VSTPlugin::Instance(const char *dllname) strcpy(_sProductName,str1.c_str()); } + if(*_sProductName) { + char tmp[256]; + 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; } @@ -131,9 +145,25 @@ void VSTPlugin::Free() // Called also in destruction 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) { FreeLibrary(h_dll); h_dll = NULL; } - } + +#ifdef FLEXT_DEBUG + flext::post("Free Plugin 2 - %x",this); +#endif + } } void VSTPlugin::DspInit(float samplerate,int blocksize) @@ -246,8 +276,10 @@ void VSTPlugin::StartEditing(WHandle h) void VSTPlugin::StopEditing() { - Dispatch(effEditClose); - hwnd = NULL; + if(Is()) { + Dispatch(effEditClose); + hwnd = NULL; + } } void VSTPlugin::Visible(bool vis) @@ -359,12 +391,25 @@ void VSTPlugin::SetPos(int x,int y,bool upd) } } +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); + } +} void VSTPlugin::processReplacing( float **inputs, float **outputs, long sampleframes ) { _pEffect->processReplacing( _pEffect , inputs , outputs , sampleframes ); - } void VSTPlugin::process( float **inputs, float **outputs, long sampleframes ) diff --git a/externals/grill/vst/src/VstHost.h b/externals/grill/vst/src/VstHost.h index 00b5164f..6fa2008b 100644 --- a/externals/grill/vst/src/VstHost.h +++ b/externals/grill/vst/src/VstHost.h @@ -130,6 +130,10 @@ public: 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(); } protected: @@ -175,7 +179,9 @@ protected: void SendMidi(); char _midichannel; - int posx,posy; + int posx,posy; // Window position + bool caption; // Window border + std::string title; // Window title }; #endif diff --git a/externals/grill/vst/src/main.cpp b/externals/grill/vst/src/main.cpp index 00804e53..fa405686 100644 --- a/externals/grill/vst/src/main.cpp +++ b/externals/grill/vst/src/main.cpp @@ -19,7 +19,7 @@ WARRANTIES, see the file, "license.txt," in this distribution. #include <string> -#define VST_VERSION "0.1.0pre14" +#define VST_VERSION "0.1.0pre15" class vst: @@ -50,6 +50,10 @@ protected: 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 t_symbol *t) { if(plug) plug->SetTitle(GetString(t)); } + V mg_wintitle(const t_symbol *&t) const { t = plug?MakeSymbol(plug->GetTitle()):sym__; } V mg_chnsin(I &c) const { c = plug?plug->GetNumInputs():0; } V mg_chnsout(I &c) const { c = plug?plug->GetNumOutputs():0; } @@ -143,6 +147,8 @@ private: FLEXT_ATTRVAR_B(echoparam) FLEXT_CALLVAR_I(mg_winx,ms_winx) FLEXT_CALLVAR_I(mg_winy,ms_winy) + FLEXT_CALLVAR_B(mg_wincaption,ms_wincaption) + FLEXT_CALLVAR_S(mg_wintitle,ms_wintitle) FLEXT_CALLGET_I(mg_chnsin) FLEXT_CALLGET_I(mg_chnsout) @@ -201,6 +207,8 @@ V vst::Setup(t_classid c) FLEXT_CADDATTR_VAR1(c,"echo",echoparam); FLEXT_CADDATTR_VAR(c,"x",mg_winx,ms_winx); FLEXT_CADDATTR_VAR(c,"y",mg_winy,ms_winy); + FLEXT_CADDATTR_VAR(c,"caption",mg_wincaption,ms_wincaption); + FLEXT_CADDATTR_VAR(c,"title",mg_wintitle,ms_wintitle); FLEXT_CADDATTR_GET(c,"ins",mg_chnsin); FLEXT_CADDATTR_GET(c,"outs",mg_chnsout); @@ -246,8 +254,8 @@ vst::~vst() V vst::ClearPlug() { if(plug) { - ms_edit(false); - ClearBuf(); + plug->Edit(false); + ClearBuf(); // needs valid plug delete plug; plug = NULL; } } |