diff options
Diffstat (limited to 'externals/grill/vst/src')
-rw-r--r-- | externals/grill/vst/src/editor.h | 5 | ||||
-rw-r--r-- | externals/grill/vst/src/editorwin.hpp | 197 | ||||
-rw-r--r-- | externals/grill/vst/src/main.cpp | 126 | ||||
-rw-r--r-- | externals/grill/vst/src/vstedit.cpp | 52 | ||||
-rw-r--r-- | externals/grill/vst/src/vsthost.cpp | 159 | ||||
-rw-r--r-- | externals/grill/vst/src/vsthost.h | 74 | ||||
-rw-r--r-- | externals/grill/vst/src/vstmaster.cpp | 2 | ||||
-rw-r--r-- | externals/grill/vst/src/vstparam.cpp | 1 |
8 files changed, 404 insertions, 212 deletions
diff --git a/externals/grill/vst/src/editor.h b/externals/grill/vst/src/editor.h index ad03f59c..7c5831e7 100644 --- a/externals/grill/vst/src/editor.h +++ b/externals/grill/vst/src/editor.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. */ @@ -20,6 +20,7 @@ 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); +void HandleEditor(VSTPlugin *p,bool h); +void FrontEditor(VSTPlugin *p); #endif // __EDITOR_H diff --git a/externals/grill/vst/src/editorwin.hpp b/externals/grill/vst/src/editorwin.hpp index 29e63db6..9d97771b 100644 --- a/externals/grill/vst/src/editorwin.hpp +++ b/externals/grill/vst/src/editorwin.hpp @@ -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. */ @@ -37,12 +37,13 @@ static LRESULT CALLBACK wndproc(HWND hwnd,UINT msg,WPARAM wp,LPARAM lp) // Initialize the window. plug->StartEditing(hwnd); break; + case WM_CLOSE: #ifdef FLEXT_LOGGING flext::post("WM_CLOSE"); #endif - // plug could already have been unloaded... - plug->StopEditing(); // this sets plug->hwnd = NULL + plug->StopEditing(); + DestroyWindow(hwnd); break; case WM_DESTROY: @@ -57,7 +58,26 @@ static LRESULT CALLBACK wndproc(HWND hwnd,UINT msg,WPARAM wp,LPARAM lp) case WM_ENTERIDLE: plug->EditorIdle(); break; +#if 0 + case WM_WINDOWPOSCHANGED: { + // ignore after WM_CLOSE so that x,y positions are preserved + if(!plug->IsEdited()) break; + WINDOWPOS *w = (WINDOWPOS *)lp; + + WINDOWINFO winfo; + winfo.cbSize = sizeof(winfo); + GetWindowInfo(hwnd,&winfo); + int cpx = winfo.rcWindow.left-winfo.rcClient.left; + int cpy = winfo.rcWindow.top-winfo.rcClient.top; + int csx = winfo.rcWindow.right-winfo.rcClient.right-cpx; + int csy = winfo.rcWindow.bottom-winfo.rcClient.bottom-cpy; + // send normalized coordinates to plugin + plug->SetPos(w->x+cpx,w->y+cpy,false); + plug->SetSize(w->cx+csx,w->cy+csy,false); + return 0; + } +#else case WM_MOVE: { // ignore after WM_CLOSE so that x,y positions are preserved if(!plug->IsEdited()) break; @@ -65,12 +85,36 @@ static LRESULT CALLBACK wndproc(HWND hwnd,UINT msg,WPARAM wp,LPARAM lp) 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_LOGGING - flext::post("WM_MOVE x/y=%i/%i",x,y); -#endif + + WINDOWINFO winfo; + winfo.cbSize = sizeof(winfo); + GetWindowInfo(hwnd,&winfo); + int px = winfo.rcWindow.left-winfo.rcClient.left; + int py = winfo.rcWindow.top-winfo.rcClient.top; + // send normalized coordinates to plugin + plug->SetPos(x+px,y+py,false); + break; + } + + case WM_SIZE: { + 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) + + WINDOWINFO winfo; + winfo.cbSize = sizeof(winfo); + GetWindowInfo(hwnd,&winfo); + int px = winfo.rcWindow.left-winfo.rcClient.left; + int py = winfo.rcWindow.top-winfo.rcClient.top; + int sx = winfo.rcWindow.right-winfo.rcClient.right-px; + int sy = winfo.rcWindow.bottom-winfo.rcClient.bottom-py; + // send normalized coordinates to plugin + plug->SetSize(x+sx,y+sy,false); break; } +#endif #if 0 // NOT needed for Windows case WM_PAINT: { @@ -86,16 +130,9 @@ static LRESULT CALLBACK wndproc(HWND hwnd,UINT msg,WPARAM wp,LPARAM lp) break; } #endif - -#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); - // 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 + case WM_SHOWWINDOW: + plug->Visible(wp != FALSE,false); + break; default: #ifdef FLEXT_LOGGING @@ -107,22 +144,25 @@ static LRESULT CALLBACK wndproc(HWND hwnd,UINT msg,WPARAM wp,LPARAM lp) return res; } -static void windowsize(HWND wnd,int x,int y,int w,int h,bool caption,LONG flags = 0) +static void windowsize(HWND wnd,int x,int y,int w,int h) { - WINDOWINFO winfo; + // pre correction + WINDOWINFO winfo; winfo.cbSize = sizeof(winfo); GetWindowInfo(wnd,&winfo); + int sx1 = (winfo.rcWindow.right-winfo.rcClient.right)-(winfo.rcWindow.left-winfo.rcClient.left); + int sy1 = (winfo.rcWindow.bottom-winfo.rcClient.bottom)-(winfo.rcWindow.top-winfo.rcClient.top); - int cy = caption?GetSystemMetrics(SM_CYCAPTION):0; + // First reflect new state in flags + SetWindowPos(wnd,NULL,0,0,0,0,SWP_NOMOVE|SWP_NOSIZE|SWP_NOZORDER|SWP_FRAMECHANGED); - 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 - ); + // post correction + GetWindowInfo(wnd,&winfo); + int sx2 = (winfo.rcWindow.right-winfo.rcClient.right)-(winfo.rcWindow.left-winfo.rcClient.left); + int sy2 = (winfo.rcWindow.bottom-winfo.rcClient.bottom)-(winfo.rcWindow.top-winfo.rcClient.top); + // set pos, size and flags + SetWindowPos(wnd,NULL,x,y,w+sx2-sx1,h+sy2-sy1,SWP_NOZORDER); } static void threadfun(flext::thr_params *p) @@ -137,14 +177,18 @@ static void threadfun(flext::thr_params *p) wndmap[thrid] = plug; mapmutex.Unlock(); - char tmp[256]; sprintf(tmp,"vst~ - %s",plug->GetName()); - HWND wnd = CreateWindow( + // Get size from plugin + ERect r; + plug->GetEditorRect(r); + + HWND wnd = CreateWindowEx( + plug->GetHandle()?WS_EX_APPWINDOW:WS_EX_TOOLWINDOW, WCLNAME,tmp, - (plug->GetCaption()?WS_BORDER|WS_CAPTION:0)|WS_POPUP|WS_SYSMENU|WS_MINIMIZEBOX, - CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT, + WS_POPUP|WS_SYSMENU|WS_MINIMIZEBOX, // no border for the beginning to set proper coordinates + plug->GetX(),plug->GetY(),r.right-r.left,r.bottom-r.top, NULL,NULL, hinstance,NULL ); @@ -152,34 +196,30 @@ static void threadfun(flext::thr_params *p) if(!wnd) FLEXT_LOG1("wnd == NULL: %i",GetLastError()); else { -// plug->Dispatch(effEditOpen , 0 , 0 , wnd, 0.0f ); // Done in WNDPROC!! - /* - CString str = theApp->GetProfileString( "VSTPos" , plug->GetName() , "10,10"); - int idx = str.Find(","); - CString x = str.Left( idx ); - CString y = str.Right( idx ); - printf(" index is %d left is %s and right is %s" , idx , x , y); - */ - -// plug->Dispatch(effEditTop,0,0, 0,0.0f); - // printf("Dispatched to the top\n"); - - SetTimer(wnd,0,TIMER_INTERVAL,NULL); - - 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_LOGGING - flext::post("Editor rect left/top=%i/%i, right/bottom=%i/%i",r.left,r.top,r.right,r.bottom); -#endif + // idle timer + SetTimer(wnd,0,TIMER_INTERVAL,NULL); + + // set caption style + CaptionEditor(plug,plug->GetCaption()); + + if(plug->IsVisible()) { + SetForegroundWindow(wnd); + ShowWindow(wnd,1); + + // notify plugin + // plug->Dispatch(effEditTop,0,0,0,0); + } + else + ShowWindow(wnd,0); - // SetFocus(); + try + { - // Message pump + // Message loop MSG msg; BOOL bRet; while( (bRet = GetMessage( &msg, NULL, 0, 0 )) != 0) { - if (bRet == -1) { + if(bRet == -1) { // handle the error and possibly exit FLEXT_LOG1("GetMessage error: %i",GetLastError()); } @@ -188,9 +228,18 @@ static void threadfun(flext::thr_params *p) DispatchMessage(&msg); } } - } -// UnregisterClass(wcx.lpszClassName,hinstance); + } + + catch(exception &e) { + flext::post("vst~ - exception caught, exiting: %s",e.what()); + } + catch(...) { + flext::post("vst~ - exception caught, exiting"); + } + + if(plug) plug->EditingEnded(); + } mapmutex.Lock(); wndmap.erase(thrid); @@ -235,7 +284,7 @@ void StopEditor(VSTPlugin *p) flext::post("Stop editor 1"); #endif PostMessage(p->EditorHandle(),WM_CLOSE,0,0); - flext::StopThread(threadfun,reinterpret_cast<flext::thr_params *>(p)); +// flext::StopThread(threadfun,reinterpret_cast<flext::thr_params *>(p)); #ifdef FLEXT_LOGGING flext::post("Stop editor 2"); #endif @@ -249,21 +298,18 @@ void ShowEditor(VSTPlugin *p,bool show) void MoveEditor(VSTPlugin *p,int x,int y) { 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 - ); + SetWindowPos(wnd,NULL,x,y,0,0,SWP_NOSIZE|SWP_NOZORDER); } void SizeEditor(VSTPlugin *p,int x,int y) { - SetWindowPos(p->EditorHandle(),NULL,0,0,x,y,SWP_NOMOVE|SWP_NOZORDER); + HWND wnd = p->EditorHandle(); + SetWindowPos(wnd,NULL,0,0,x,y,SWP_NOMOVE|SWP_NOZORDER); +} + +void FrontEditor(VSTPlugin *p) +{ + SetForegroundWindow(p->EditorHandle()); } void CaptionEditor(VSTPlugin *plug,bool c) @@ -274,18 +320,27 @@ void CaptionEditor(VSTPlugin *plug,bool c) 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); + windowsize(wnd,plug->GetX(),plug->GetY(),plug->GetW(),plug->GetH()); } } +void HandleEditor(VSTPlugin *plug,bool h) +{ + HWND wnd = plug->EditorHandle(); + bool v = plug->IsVisible(); + if(v) ShowWindow(wnd,FALSE); + SetWindowLong(wnd,GWL_EXSTYLE,h?WS_EX_APPWINDOW:WS_EX_TOOLWINDOW); + if(v) ShowWindow(wnd,TRUE); +} + void TitleEditor(VSTPlugin *p,const char *t) { SetWindowText(p->EditorHandle(),t); } +/* bool IsEditorShown(const VSTPlugin *p) { return IsWindowVisible(p->EditorHandle()) != FALSE; } +*/
\ No newline at end of file diff --git a/externals/grill/vst/src/main.cpp b/externals/grill/vst/src/main.cpp index 9a4b3a6c..d1c369c3 100644 --- a/externals/grill/vst/src/main.cpp +++ b/externals/grill/vst/src/main.cpp @@ -26,7 +26,7 @@ WARRANTIES, see the file, "license.txt," in this distribution. #endif -#define VST_VERSION "0.1.0pre21" +#define VST_VERSION "0.1.0pre23" class vst @@ -64,12 +64,19 @@ protected: void mg_winx(int &x) const { x = plug?plug->GetX():0; } void mg_winy(int &y) const { y = plug?plug->GetY():0; } + void mg_winw(int &x) const { x = plug?plug->GetW():0; } + void mg_winh(int &y) const { y = plug?plug->GetH():0; } void ms_winx(int x) { if(plug) plug->SetX(x); } void ms_winy(int y) { if(plug) plug->SetY(y); } + void ms_winw(int x) { if(plug) plug->SetW(x); } + void ms_winh(int y) { if(plug) plug->SetH(y); } void ms_wincaption(bool c) { if(plug) plug->SetCaption(c); } void mg_wincaption(bool &c) const { c = plug && plug->GetCaption(); } + void ms_winhandle(bool c) { if(plug) plug->SetHandle(c); } + void mg_winhandle(bool &c) const { c = plug && plug->GetHandle(); } void ms_wintitle(const AtomList &t); void mg_wintitle(AtomList &t) const { if(plug) { t(1); SetString(t[0],plug->GetTitle()); } } + void m_winfront() const { if(plug) plug->ToFront(); } void mg_chnsin(int &c) const { c = plug?plug->GetNumInputs():0; } void mg_chnsout(int &c) const { c = plug?plug->GetNumOutputs():0; } @@ -98,13 +105,19 @@ protected: 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 mg_channel(int &chn) const { chn = plug?plug->GetChannel():0; } + void ms_channel(int chn) { if(plug) plug->SetChannel(chn); } + void m_note(int note,int vel); void m_noteoff(int note) { m_note(note,0); } + void m_programchange(int ctrl_value) { if(plug) plug->AddProgramChange(ctrl_value); } + void m_ctrlchange(int control,int ctrl_value) { if(plug) plug->AddControlChange(control,ctrl_value); } + void m_aftertouch(int ctrl_value) { if(plug) plug->AddAftertouch(ctrl_value); } + void m_polyaftertouch(int note,int ctrl_value) { if(plug) plug->AddPolyAftertouch(note,ctrl_value); } + void m_pitchbend(int ctrl_value) { if(plug) plug->AddPitchBend(ctrl_value); } + + void mg_dumpevents(bool &ev) const { ev = plug?plug->GetEvents():false; } + void ms_dumpevents(bool ev) { if(plug) plug->SetEvents(ev); } void mg_playing(bool &p) { p = plug && plug->GetPlaying(); } void ms_playing(bool p) { if(plug) plug->SetPlaying(p); } @@ -140,7 +153,7 @@ private: VSTPlugin *plug; std::string plugname,subplug; - bool echoparam,visible,bypass,mute; + bool visible,bypass,mute; int paramnames; int blsz; @@ -171,12 +184,17 @@ private: FLEXT_ATTRVAR_B(bypass) FLEXT_ATTRVAR_B(mute) -// FLEXT_CALLBACK_2(m_control,t_symptr,int) - FLEXT_CALLBACK_I(m_pitchbend) - FLEXT_CALLBACK_I(m_aftertouch) - FLEXT_CALLBACK_I(m_programchange) + FLEXT_CALLVAR_I(mg_channel,ms_channel) + FLEXT_CALLBACK_II(m_note) + FLEXT_CALLBACK_I(m_noteoff) FLEXT_CALLBACK_II(m_ctrlchange) + FLEXT_CALLBACK_I(m_aftertouch) + FLEXT_CALLBACK_II(m_polyaftertouch) + FLEXT_CALLBACK_I(m_pitchbend) + + FLEXT_CALLVAR_B(mg_dumpevents,ms_dumpevents) + FLEXT_CALLBACK_I(m_programchange) FLEXT_CALLVAR_I(mg_program,ms_program) FLEXT_CALLBACK_V(mg_progname) @@ -190,14 +208,14 @@ private: FLEXT_CALLBACK_I(m_ptext) FLEXT_CALLBACK_V(m_ptexts) - FLEXT_CALLBACK_II(m_note) - FLEXT_CALLBACK_I(m_noteoff) - - FLEXT_ATTRVAR_B(echoparam) FLEXT_CALLVAR_I(mg_winx,ms_winx) FLEXT_CALLVAR_I(mg_winy,ms_winy) + FLEXT_CALLVAR_I(mg_winw,ms_winw) + FLEXT_CALLVAR_I(mg_winh,ms_winh) FLEXT_CALLVAR_B(mg_wincaption,ms_wincaption) + FLEXT_CALLVAR_B(mg_winhandle,ms_winhandle) FLEXT_CALLVAR_V(mg_wintitle,ms_wintitle) + FLEXT_CALLBACK(m_winfront) FLEXT_CALLGET_I(mg_chnsin) FLEXT_CALLGET_I(mg_chnsout) @@ -250,12 +268,15 @@ void vst::Setup(t_classid c) FLEXT_CADDATTR_VAR1(c,"mute",mute); FLEXT_CADDMETHOD_(c,0,"print",m_print); - FLEXT_CADDMETHOD_II(c,0,"note",m_note); + FLEXT_CADDATTR_VAR(c,"channel",mg_channel,ms_channel); FLEXT_CADDMETHOD_I(c,0,"noteoff",m_noteoff); -// FLEXT_CADDMETHOD_2(c,0,"control",m_control,t_symptr,int); - FLEXT_CADDMETHOD_(c,0,"pbend",m_pitchbend); - FLEXT_CADDMETHOD_(c,0,"atouch",m_aftertouch); + FLEXT_CADDMETHOD_II(c,0,"note",m_note); + FLEXT_CADDMETHOD_II(c,0,"patouch",m_polyaftertouch); FLEXT_CADDMETHOD_II(c,0,"ctlchg",m_ctrlchange); + FLEXT_CADDMETHOD_(c,0,"atouch",m_aftertouch); + FLEXT_CADDMETHOD_(c,0,"pbend",m_pitchbend); + + FLEXT_CADDATTR_VAR(c,"events",mg_dumpevents,ms_dumpevents); FLEXT_CADDMETHOD_(c,0,"progchg",m_programchange); FLEXT_CADDATTR_VAR(c,"program",mg_program,ms_program); @@ -270,11 +291,14 @@ void vst::Setup(t_classid c) FLEXT_CADDMETHOD_(c,0,"getptext",m_ptext); FLEXT_CADDMETHOD_(c,0,"getptext",m_ptexts); - FLEXT_CADDATTR_VAR1(c,"echo",echoparam); FLEXT_CADDATTR_VAR(c,"x",mg_winx,ms_winx); FLEXT_CADDATTR_VAR(c,"y",mg_winy,ms_winy); - FLEXT_CADDATTR_VAR(c,"caption",mg_wincaption,ms_wincaption); + FLEXT_CADDATTR_VAR(c,"w",mg_winw,ms_winw); + FLEXT_CADDATTR_VAR(c,"h",mg_winh,ms_winh); FLEXT_CADDATTR_VAR(c,"title",mg_wintitle,ms_wintitle); + FLEXT_CADDATTR_VAR(c,"caption",mg_wincaption,ms_wincaption); + FLEXT_CADDATTR_VAR(c,"handle",mg_winhandle,ms_winhandle); + FLEXT_CADDMETHOD_(c,0,"front",m_winfront); FLEXT_CADDATTR_GET(c,"ins",mg_chnsin); FLEXT_CADDATTR_GET(c,"outs",mg_chnsout); @@ -318,7 +342,7 @@ 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) + bypass(false),mute(false),paramnames(0) { #if FLEXT_OS == FLEXT_OS_WIN // this is necessary for Waveshell @@ -346,9 +370,9 @@ vst::~vst() void vst::ClearPlug() { if(plug) { - plug->Edit(false); ClearBuf(); // needs valid plug - delete plug; plug = NULL; + VSTPlugin::Delete(plug); + plug = NULL; } } @@ -440,15 +464,17 @@ static std::string findFilePath(const std::string &path,const std::string &dllna return std::string(); } - +// \todo this should be in the background, because it can take some time +// ideally vst would get a response from VSTPlugin when readily, loaded and +// vst would dump out a respective signal to the patcher bool vst::LoadPlug() { if(plug) ClearPlug(); - plug = new VSTPlugin(this); + VSTPlugin *p = VSTPlugin::New(this); // try loading the dll from the raw filename - bool ok = plug->Instance(plugname.c_str(),subplug.c_str()); + bool ok = p->Instance(plugname.c_str(),subplug.c_str()); if(ok) FLEXT_LOG("raw filename loaded fine"); else { @@ -468,7 +494,7 @@ bool vst::LoadPlug() dllname += "\\"; dllname += name; - ok = plug->Instance(dllname.c_str()); + ok = p->Instance(dllname.c_str()); } #endif } @@ -497,7 +523,7 @@ bool vst::LoadPlug() realpath += plugname; FLEXT_LOG1("trying %s",(const char *)realpath.c_str()); - ok = plug->Instance(realpath.c_str()); + ok = p->Instance(realpath.c_str()); if(ok) { FLEXT_LOG("plugin loaded via VST_PATH"); break; @@ -505,7 +531,7 @@ bool vst::LoadPlug() } tok = strtok( NULL , ";" ); - if(!tok) post("%s - couldn't find plugin",thisName()); +// if(!tok) post("%s - couldn't find plugin",thisName()); } delete[] tok_path; @@ -514,10 +540,12 @@ bool vst::LoadPlug() if(!ok) { post("%s - unable to load plugin '%s'",thisName(),plugname.c_str()); - ClearPlug(); + VSTPlugin::Delete(p); } - else + else { + plug = p; InitPlug(); + } return ok; } @@ -674,32 +702,6 @@ void vst::CbSignal() flext_dsp::CbSignal(); } - -#if 0 - -void vst::m_control(const t_symbol *ctrl_name,int ctrl_value) -{ - if(!plug) return; - - int parm_num = 0; - - if (!*GetString(ctrl_name) || !strlen(GetString(ctrl_name))) { - error ("plugin~: control messages must have a name and a value"); - return; - } - //parm_num = vst_tilde_get_parm_number (x, ctrl_name->s_name); - //if (parm_num) - //{ - //vst_tilde_set_control_input_by_index (x, parm_num - 1, ctrl_value); - //} - //else - //{ - //vst_tilde_set_control_input_by_name (x, ctrl_name->s_name, ctrl_value); - //} -} - -#endif - void vst::mg_progname(int argc,const t_atom *argv) const { if(plug) { @@ -788,8 +790,8 @@ void vst::m_print(int ac,const t_atom *av) } if ( header ) { - post("VST~ plugin: %s " , plug->GetName() ); - post("made by: %s " , plug->GetVendorName() ); + post("VST~ plugin: %s ", plug->GetName() ); + post("made by: %s ", plug->GetVendorName() ); post("parameters %d\naudio: %d in(s)/%d out(s) \nLoaded from library \"%s\".\n", plug->GetNumParams(), CntInSig(), @@ -868,12 +870,12 @@ void vst::ms_param(int pnum,float val) { if(!plug || pnum < 0 || pnum >= plug->GetNumParams()) return; - float xval = plug->GetParamValue( pnum ); +// float xval = plug->GetParamValue( pnum ); // if(xval <= 1.0f) // What's that???? if(true) { plug->SetParamFloat( pnum, val ); - if(echoparam) display_parameter(pnum , true ); +// if(echoparam) display_parameter(pnum , true ); } else FLEXT_ASSERT(false); diff --git a/externals/grill/vst/src/vstedit.cpp b/externals/grill/vst/src/vstedit.cpp index 804e83ca..1536b9d3 100644 --- a/externals/grill/vst/src/vstedit.cpp +++ b/externals/grill/vst/src/vstedit.cpp @@ -27,50 +27,56 @@ 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;
- }
+ if(Is() && IsEdited())
+ Dispatch(effEditClose);
}
-void VSTPlugin::Visible(bool vis)
+void VSTPlugin::Visible(bool vis,bool upd)
{
- if(Is() && IsEdited()) ShowEditor(this,vis);
+ visible = vis;
+ if(upd && Is() && IsEdited()) ShowEditor(this,vis);
}
-bool VSTPlugin::IsVisible() const
-{
- return Is() && IsEdited() && IsEditorShown(this);
+void VSTPlugin::SetPos(int x,int y,bool upd)
+{
+ posx = x; posy = y;
+ if(upd && Is() && IsEdited()) MoveEditor(this,posx,posy);
}
-
-void VSTPlugin::SetPos(int x,int y,bool upd)
+void VSTPlugin::SetSize(int x,int y,bool upd)
{
- if(Is()) {
- posx = x; posy = y;
- if(upd && IsEdited()) MoveEditor(this,posx,posy);
- }
+ sizex = x; sizey = y;
+ if(upd && Is() && IsEdited()) SizeEditor(this,sizex,sizey);
}
void VSTPlugin::SetCaption(bool c)
{
- if(Is()) {
- caption = c;
- if(IsEdited()) CaptionEditor(this,c);
- }
+ caption = c;
+ if(Is() && IsEdited()) CaptionEditor(this,c);
+}
+
+void VSTPlugin::SetHandle(bool h)
+{
+ handle = h;
+ if(Is() && IsEdited()) HandleEditor(this,h);
}
void VSTPlugin::SetTitle(const char *t)
{
- if(Is()) {
- title = t;
- if(IsEdited()) TitleEditor(this,t);
+ title = t;
+ if(Is() && IsEdited()) TitleEditor(this,t);
+}
+
+void VSTPlugin::ToFront()
+{
+ if(Is() && IsEdited()) {
+ FrontEditor(this);
+ Dispatch(effEditTop,0,0,vendorname);
}
}
diff --git a/externals/grill/vst/src/vsthost.cpp b/externals/grill/vst/src/vsthost.cpp index 3b9d6241..5f2443fc 100644 --- a/externals/grill/vst/src/vsthost.cpp +++ b/externals/grill/vst/src/vsthost.cpp @@ -8,7 +8,9 @@ WARRANTIES, see the file, "license.txt," in this distribution. */ #include "vsthost.h" - +#include "editor.h" +#include <exception> +#include "flcontainers.h" const t_symbol *VSTPlugin::sym_param, @@ -22,8 +24,22 @@ const t_symbol *VSTPlugin::sym_ev_, *VSTPlugin::sym_midi[8]; + +class DelPlugin + : public Fifo::Cell +{ +public: + DelPlugin(VSTPlugin *p): plug(p) {} + VSTPlugin *plug; +}; + +static TypedLifo<DelPlugin> todel; +flext::ThrCond VSTPlugin::thrcond; + void VSTPlugin::Setup() { + LaunchThread(worker); + sym_param = flext::MakeSymbol("param"); sym_event = flext::MakeSymbol("event"); sym_evmidi = flext::MakeSymbol("midi"); @@ -34,22 +50,23 @@ void VSTPlugin::Setup() 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[0] = flext::MakeSymbol("noteoff"); + sym_midi[1] = flext::MakeSymbol("note"); + sym_midi[2] = flext::MakeSymbol("atouch"); + sym_midi[3] = flext::MakeSymbol("ctlchg"); sym_midi[4] = flext::MakeSymbol("progchg"); - sym_midi[5] = flext::MakeSymbol("chnafter"); - sym_midi[6] = flext::MakeSymbol("pitchbend"); - sym_midi[7] = sym__; + sym_midi[5] = flext::MakeSymbol("atouch"); + sym_midi[6] = flext::MakeSymbol("pbend"); + sym_midi[7] = flext::MakeSymbol("sysex"); } 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) + , posx(0),posy(0),sizex(0),sizey(0) + , visible(true),caption(true),handle(false) + , midichannel(0),eventqusz(0),dumpevents(false) , paramnamecnt(0) , transchg(true) , playing(false),looping(false),feedback(false) @@ -67,7 +84,55 @@ VSTPlugin::~VSTPlugin() Free(); } +VSTPlugin *VSTPlugin::New(Responder *resp) +{ + FLEXT_ASSERT(resp); + return new VSTPlugin(resp); +} + +void VSTPlugin::Delete(VSTPlugin *p) +{ + FLEXT_ASSERT(p); + + // tell plugin to close editor! + StopEditor(p); + // transfer to deletion thread + todel.Push(new DelPlugin(p)); + thrcond.Signal(); +} + +void VSTPlugin::worker(thr_params *) +{ + TypedLifo<DelPlugin> tmp; + bool again = false; + for(;;) { + // wait for signal + if(again) { + thrcond.TimedWait(0.01); + again = false; + } + else + thrcond.Wait(); + + DelPlugin *p; + while((p = todel.Pop()) != NULL) { + // see if editing has stopped + if(p && p->plug->hwnd == NULL) { + // yes, it is now safe to delete the plug + delete p->plug; + delete p; + } + else { + tmp.Push(p); + again = true; + } + } + // put back remaining entries + while((p = tmp.Pop()) != NULL) todel.Push(p); + } +} + #if FLEXT_OS == FLEXT_OS_MAC OSStatus FSPathMakeFSSpec(const UInt8 *path,FSSpec *spec,Boolean *isDirectory) /* can be NULL */ { @@ -208,9 +273,17 @@ bool VSTPlugin::InstPlugin(long plugid) FLEXT_ASSERT(pluginmain && audiomaster); //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"); + try { effect = pluginmain(audiomaster); } + catch(exception &e) { + flext::post("vst~ - caught exception while instantiating plugin: %s",e.what()); + } + catch(...) { + flext::post("vst~ - caught exception while instantiating plugin"); + } + + if(!effect) + return false; + else if(effect->magic != kEffectMagic) { effect = NULL; return false; } @@ -219,13 +292,19 @@ bool VSTPlugin::InstPlugin(long plugid) bool VSTPlugin::Instance(const char *name,const char *subname) { - bool ok = effect != NULL; + bool ok = false; + FLEXT_ASSERT(effect == NULL); + try { + +/* if(!ok && dllname != name) { FreePlugin(); // freshly load plugin ok = NewPlugin(name) && InstPlugin(); } +*/ + ok = NewPlugin(name) && InstPlugin(); if(ok && subname && *subname && Dispatch(effGetPlugCategory) == kPlugCategShell) { // sub plugin-name given -> scan plugs @@ -294,37 +373,53 @@ bool VSTPlugin::Instance(const char *name,const char *subname) Dispatch(effGetVendorString,0,0,vendorname); } + } + catch(exception &e) { + flext::post("vst~ - caught exception while loading plugin: %s",e.what()); + ok = false; + } + catch(...) { + flext::post("vst~ - Caught exception while loading plugin"); + ok = false; + } + if(!ok) Free(); return ok; } -void VSTPlugin::Free() // Called also in destruction +void VSTPlugin::Free() { - if(effect) { - Edit(false); + // This should only also in destruction - // shut down plugin - Dispatch(effMainsChanged, 0, 0); - Dispatch(effClose); - } + try { + if(effect) { + FLEXT_ASSERT(!IsEdited()); - // \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 + // shut down plugin + Dispatch(effMainsChanged, 0, 0); + Dispatch(effClose); + } + } + catch(...) {} FreePlugin(); } void VSTPlugin::DspInit(float sr,int blsz) { - // 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); + try { + // 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); + } + catch(exception &e) { + flext::post("vst~ - caught exception while initializing dsp: %s",e.what()); + } + catch(...) { + flext::post("vst~ - caught exception while initializing dsp"); + } } void VSTPlugin::ListPlugs(const t_symbol *sym) const diff --git a/externals/grill/vst/src/vsthost.h b/externals/grill/vst/src/vsthost.h index bda1d538..0b1adef0 100644 --- a/externals/grill/vst/src/vsthost.h +++ b/externals/grill/vst/src/vsthost.h @@ -40,19 +40,27 @@ public: virtual void Respond(const t_symbol *sym,int argc = 0,const t_atom *argv = NULL) = 0; }; + class VSTPlugin: public flext { public: + static VSTPlugin *New(Responder *resp); + static void Delete(VSTPlugin *p); static void Setup(); + bool Instance(const char *plug,const char *subplug = NULL); + void DspInit(float samplerate,int blocksize); + +private: VSTPlugin(Responder *resp); ~VSTPlugin(); - bool Instance(const char *plug,const char *subplug = NULL); + static ThrCond thrcond; + static void worker(thr_params *p); + void Free(); - void DspInit(float samplerate,int blocksize); ////////////////////////////////////////////////////////////////////////////// @@ -119,81 +127,104 @@ private: public: void SetPos(int x,int y,bool upd = true); + void SetSize(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); } + void SetW(int x,bool upd = true) { SetSize(x,sizey,upd); } + void SetH(int y,bool upd = true) { SetSize(sizex,y,upd); } int GetX() const { return posx; } int GetY() const { return posy; } + int GetW() const { return sizex; } + int GetH() const { return sizey; } void SetCaption(bool b); bool GetCaption() const { return caption; } + void SetHandle(bool h); + bool GetHandle() const { return handle; } void SetTitle(const char *t); const char *GetTitle() const { return title.c_str(); } + void ToFront(); void Edit(bool open); - void StartEditing(WHandle h ); + void StartEditing(WHandle h); void StopEditing(); bool IsEdited() const { return hwnd != NULL; } WHandle EditorHandle() const { return hwnd; } + void EditingEnded() { hwnd = NULL; thrcond.Signal(); } void GetEditorRect(ERect &er) const { ERect *r; Dispatch(effEditGetRect,0,0,&r); er = *r; } void EditorIdle() { Dispatch(effEditIdle); } - void Visible(bool vis); - bool IsVisible() const; + void Visible(bool vis,bool upd = true); + bool IsVisible() const { return visible; } void Paint(ERect &r) const { Dispatch(effEditDraw,0,0,&r); } private: - int posx,posy; // Window position + bool visible; + int posx,posy,sizex,sizey; // Window position bool caption; // Window border + bool handle; // Window handle (like taskbar button) std::string title; // Window title ////////////////////////////////////////////////////////////////////////////// public: enum { - MIDI_NOTEON = 144, - MIDI_NOTEOFF = 128, - MIDI_POLYAFTERTOUCH = 160, - MIDI_CONTROLCHANGE = 176, - MIDI_PROGRAMCHANGE = 192, - MIDI_AFTERTOUCH = 208, - MIDI_PITCHBEND = 224 + MIDI_NOTEOFF = 0x80, + MIDI_NOTEON = 0x90, + MIDI_POLYAFTERTOUCH = 0xa0, + MIDI_CONTROLCHANGE = 0xb0, + MIDI_PROGRAMCHANGE = 0xc0, + MIDI_AFTERTOUCH = 0xd0, + MIDI_PITCHBEND = 0xe0, + MIDI_SYSEX = 0xf0, }; + void SetEvents(bool ev) { dumpevents = ev; } + bool GetEvents() const { return dumpevents; } + bool AddMIDI(unsigned char data0,unsigned char data1 = 0,unsigned char data2 = 0); static int range(int value,int mn = 0,int mx = 127) { return value < mn?mn:(value > mx?mx:value); } - bool AddNoteOn(unsigned char note,unsigned char speed,unsigned char midichannel = 0) + void SetChannel(int channel) { midichannel = range(channel,0,0xf); } + int GetChannel() const { return midichannel; } + + bool AddNoteOn(unsigned char note,unsigned char speed /*,unsigned char midichannel = 0*/) { - return AddMIDI((char)MIDI_NOTEON|midichannel,note,speed); + return AddMIDI(MIDI_NOTEON+midichannel,note,speed); } - bool AddNoteOff(unsigned char note,unsigned char midichannel = 0) + bool AddNoteOff(unsigned char note /*,unsigned char midichannel = 0*/) { - return AddMIDI((char)MIDI_NOTEOFF|midichannel,note,0); + return AddMIDI(MIDI_NOTEOFF+midichannel,note,0); } void AddControlChange(int control,int value) { - AddMIDI(MIDI_CONTROLCHANGE+(midichannel&0xf),range(control),range(value)); + AddMIDI(MIDI_CONTROLCHANGE+midichannel,range(control),range(value)); } void AddProgramChange(int value) { - AddMIDI(MIDI_PROGRAMCHANGE+(midichannel&0xf),range(value),0); + AddMIDI(MIDI_PROGRAMCHANGE+midichannel,range(value),0); } void AddPitchBend(int value) { - AddMIDI(MIDI_PITCHBEND+(midichannel&0xf),((value>>7)&127),(value&127)); + AddMIDI(MIDI_PITCHBEND+midichannel,((value>>7)&127),(value&127)); } void AddAftertouch(int value) { - AddMIDI((char)MIDI_AFTERTOUCH|midichannel,range(value)); + AddMIDI(MIDI_AFTERTOUCH+midichannel,range(value)); + } + + void AddPolyAftertouch(unsigned char note,int value) + { + AddMIDI(MIDI_POLYAFTERTOUCH+midichannel,note,range(value)); } private: @@ -205,6 +236,7 @@ private: int eventqusz; char midichannel; + bool dumpevents; ////////////////////////////////////////////////////////////////////////////// diff --git a/externals/grill/vst/src/vstmaster.cpp b/externals/grill/vst/src/vstmaster.cpp index 108d8079..00a93c80 100644 --- a/externals/grill/vst/src/vstmaster.cpp +++ b/externals/grill/vst/src/vstmaster.cpp @@ -16,7 +16,7 @@ static const char *product = "vst~"; void VSTPlugin::ProcessEvent(const VstEvent &ev)
{
- if(!responder) return;
+ if(!responder && dumpevents) return;
if(ev.type == kVstMidiType) {
const VstMidiEvent &mev = (const VstMidiEvent &)ev;
diff --git a/externals/grill/vst/src/vstparam.cpp b/externals/grill/vst/src/vstparam.cpp index 30515b23..bb80263e 100644 --- a/externals/grill/vst/src/vstparam.cpp +++ b/externals/grill/vst/src/vstparam.cpp @@ -16,6 +16,7 @@ static void striptrail(char *txt) 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;
+ else break;
}
void VSTPlugin::GetParamName(int numparam,char *name) const
|