From e1095310a8186bbd977534285df0ab29423d3aa3 Mon Sep 17 00:00:00 2001 From: Robin Gareus Date: Mon, 6 Mar 2017 23:49:40 +0100 Subject: Rework VST initialization: Set the AEffect* plugin pointer before calling effOpen. effOpen may call back into the host (masterCallback) and invoke actions which depend on _plugin (eg. to call back into the plugin again) --- libs/ardour/ardour/mac_vst_plugin.h | 2 ++ libs/ardour/ardour/vst_plugin.h | 3 ++- libs/ardour/linux_vst_support.cc | 18 ++++++++++-------- libs/ardour/lxvst_plugin.cc | 9 +++++---- libs/ardour/mac_vst_plugin.cc | 16 ++++++++++++---- libs/ardour/mac_vst_support.cc | 24 +++++++++++++----------- libs/ardour/vst_plugin.cc | 12 +++++++++--- libs/ardour/windows_vst_plugin.cc | 8 ++++---- libs/fst/vstwin.c | 12 ++++++++++-- 9 files changed, 67 insertions(+), 37 deletions(-) diff --git a/libs/ardour/ardour/mac_vst_plugin.h b/libs/ardour/ardour/mac_vst_plugin.h index e5afab5e30..4eb4e41300 100644 --- a/libs/ardour/ardour/mac_vst_plugin.h +++ b/libs/ardour/ardour/mac_vst_plugin.h @@ -38,6 +38,8 @@ public: ~MacVSTPlugin (); std::string state_node_name () const { return "mac-vst"; } +protected: + void open_plugin (); }; class LIBARDOUR_API MacVSTPluginInfo : public PluginInfo diff --git a/libs/ardour/ardour/vst_plugin.h b/libs/ardour/ardour/vst_plugin.h index 50cfc5e21a..b35ef6b25e 100644 --- a/libs/ardour/ardour/vst_plugin.h +++ b/libs/ardour/ardour/vst_plugin.h @@ -103,7 +103,8 @@ public: protected: void parameter_changed_externally (uint32_t which, float val); - void set_plugin (AEffect *); + virtual void open_plugin (); + void init_plugin (); gchar* get_chunk (bool) const; int set_chunk (gchar const *, bool); void add_state (XMLNode *) const; diff --git a/libs/ardour/linux_vst_support.cc b/libs/ardour/linux_vst_support.cc index be16340f2a..44d61f7a77 100644 --- a/libs/ardour/linux_vst_support.cc +++ b/libs/ardour/linux_vst_support.cc @@ -306,14 +306,16 @@ vstfx_instantiate (VSTHandle* fhandle, audioMasterCallback amc, void* userptr) return 0; } - vstfx->plugin->dispatcher (vstfx->plugin, effOpen, 0, 0, 0, 0); - - /*May or May not need to 'switch the plugin on' here - unlikely - since FST doesn't and most plugins start up 'On' by default - I think this is the least of our worries*/ - - //vstfx->plugin->dispatcher (vstfx->plugin, effMainsChanged, 0, 1, 0, 0); - - vstfx->vst_version = vstfx->plugin->dispatcher (vstfx->plugin, effGetVstVersion, 0, 0, 0, 0); + if (!userptr) { + /* scanning.. or w/o master-callback userptr == 0, open now. + * + * Session::vst_callback needs a pointer to the AEffect + * ((VSTPlugin*)userptr)->_plugin = vstfx->plugin + * before calling effOpen, because effOpen may call back + */ + vstfx->plugin->dispatcher (vstfx->plugin, effOpen, 0, 0, 0, 0); + vstfx->vst_version = vstfx->plugin->dispatcher (vstfx->plugin, effGetVstVersion, 0, 0, 0, 0); + } vstfx->handle->plugincnt++; vstfx->wantIdle = 0; diff --git a/libs/ardour/lxvst_plugin.cc b/libs/ardour/lxvst_plugin.cc index b71f9fa378..259c5e6461 100644 --- a/libs/ardour/lxvst_plugin.cc +++ b/libs/ardour/lxvst_plugin.cc @@ -40,9 +40,10 @@ LXVSTPlugin::LXVSTPlugin (AudioEngine& e, Session& session, VSTHandle* h, int un if ((_state = vstfx_instantiate (_handle, Session::vst_callback, this)) == 0) { throw failed_constructor(); } + open_plugin (); Session::vst_current_loading_id = 0; - set_plugin (_state->plugin); + init_plugin (); } LXVSTPlugin::LXVSTPlugin (const LXVSTPlugin &other) @@ -54,17 +55,16 @@ LXVSTPlugin::LXVSTPlugin (const LXVSTPlugin &other) if ((_state = vstfx_instantiate (_handle, Session::vst_callback, this)) == 0) { throw failed_constructor(); } + open_plugin (); Session::vst_current_loading_id = 0; - _plugin = _state->plugin; - XMLNode* root = new XMLNode (other.state_node_name ()); LocaleGuard lg; other.add_state (root); set_state (*root, Stateful::loading_state_version); delete root; - set_plugin (_state->plugin); + init_plugin (); } LXVSTPlugin::~LXVSTPlugin () @@ -120,6 +120,7 @@ LXVSTPluginInfo::get_presets (bool user_only) const Session::vst_current_loading_id = atoi (unique_id); AEffect* plugin = handle->main_entry (Session::vst_callback); Session::vst_current_loading_id = 0; + plugin->user = NULL; plugin->dispatcher (plugin, effOpen, 0, 0, 0, 0); // :( int const vst_version = plugin->dispatcher (plugin, effGetVstVersion, 0, 0, NULL, 0); diff --git a/libs/ardour/mac_vst_plugin.cc b/libs/ardour/mac_vst_plugin.cc index 8fc87aaeec..b8f82325c6 100644 --- a/libs/ardour/mac_vst_plugin.cc +++ b/libs/ardour/mac_vst_plugin.cc @@ -40,9 +40,10 @@ MacVSTPlugin::MacVSTPlugin (AudioEngine& e, Session& session, VSTHandle* h, int if ((_state = mac_vst_instantiate (_handle, Session::vst_callback, this)) == 0) { throw failed_constructor (); } + open_plugin (); Session::vst_current_loading_id = 0; - set_plugin (_state->plugin); + init_plugin (); } MacVSTPlugin::MacVSTPlugin (const MacVSTPlugin &other) @@ -54,17 +55,16 @@ MacVSTPlugin::MacVSTPlugin (const MacVSTPlugin &other) if ((_state = mac_vst_instantiate (_handle, Session::vst_callback, this)) == 0) { throw failed_constructor (); } + open_plugin (); Session::vst_current_loading_id = 0; - _plugin = _state->plugin; - XMLNode* root = new XMLNode (other.state_node_name ()); LocaleGuard lg; other.add_state (root); set_state (*root, Stateful::loading_state_version); delete root; - set_plugin (_state->plugin); + init_plugin (); } MacVSTPlugin::~MacVSTPlugin () @@ -72,6 +72,13 @@ MacVSTPlugin::~MacVSTPlugin () mac_vst_close (_state); } +void +MacVSTPlugin::open_plugin () +{ + VSTPlugin::open_plugin (); + _plugin->dispatcher (mac_vst->plugin, effCanDo, 0, 0, const_cast ("hasCockosViewAsConfig"), 0.0f); +} + PluginPtr MacVSTPluginInfo::load (Session& session) { @@ -120,6 +127,7 @@ MacVSTPluginInfo::get_presets (bool user_only) const Session::vst_current_loading_id = atoi (unique_id); AEffect* plugin = handle->main_entry (Session::vst_callback); Session::vst_current_loading_id = 0; + plugin->user = NULL; plugin->dispatcher (plugin, effOpen, 0, 0, 0, 0); // :( int const vst_version = plugin->dispatcher (plugin, effGetVstVersion, 0, 0, NULL, 0); diff --git a/libs/ardour/mac_vst_support.cc b/libs/ardour/mac_vst_support.cc index 686c54f747..ae40e53a71 100644 --- a/libs/ardour/mac_vst_support.cc +++ b/libs/ardour/mac_vst_support.cc @@ -203,17 +203,19 @@ mac_vst_instantiate (VSTHandle* fhandle, audioMasterCallback amc, void* userptr) return 0; } - mac_vst->plugin->dispatcher (mac_vst->plugin, effOpen, 0, 0, 0, 0); - - /*May or May not need to 'switch the plugin on' here - unlikely - since FST doesn't and most plugins start up 'On' by default - I think this is the least of our worries*/ - - //mac_vst->plugin->dispatcher (mac_vst->plugin, effMainsChanged, 0, 1, 0, 0); - - /* configure plugin to use Cocoa View */ - mac_vst->plugin->dispatcher (mac_vst->plugin, effCanDo, 0, 0, const_cast ("hasCockosViewAsConfig"), 0.0f); - - mac_vst->vst_version = mac_vst->plugin->dispatcher (mac_vst->plugin, effGetVstVersion, 0, 0, 0, 0); + if (!userptr) { + /* scanning.. or w/o master-callback userptr == 0, open now. + * + * Session::vst_callback needs a pointer to the AEffect + * ((VSTPlugin*)userptr)->_plugin = vstfx->plugin + * before calling effOpen, because effOpen may call back + */ + mac_vst->plugin->dispatcher (mac_vst->plugin, effOpen, 0, 0, 0, 0); + mac_vst->vst_version = mac_vst->plugin->dispatcher (mac_vst->plugin, effGetVstVersion, 0, 0, 0, 0); + + /* configure plugin to use Cocoa View */ + mac_vst->plugin->dispatcher (mac_vst->plugin, effCanDo, 0, 0, const_cast ("hasCockosViewAsConfig"), 0.0f); + } mac_vst->handle->plugincnt++; mac_vst->wantIdle = 0; diff --git a/libs/ardour/vst_plugin.cc b/libs/ardour/vst_plugin.cc index 8541e8eaf7..fe601d9505 100644 --- a/libs/ardour/vst_plugin.cc +++ b/libs/ardour/vst_plugin.cc @@ -76,13 +76,19 @@ VSTPlugin::~VSTPlugin () } void -VSTPlugin::set_plugin (AEffect* e) +VSTPlugin::open_plugin () { - _plugin = e; + _plugin = _state->plugin; + assert (_plugin->user == this); // should have been set by {mac_vst|fst|lxvst}_instantiate _plugin->user = this; + _state->plugin->dispatcher (_plugin, effOpen, 0, 0, 0, 0); + _state->vst_version = _plugin->dispatcher (_plugin, effGetVstVersion, 0, 0, 0, 0); +} +void +VSTPlugin::init_plugin () +{ /* set rate and blocksize */ - _plugin->dispatcher (_plugin, effSetSampleRate, 0, 0, NULL, (float) _session.frame_rate()); _plugin->dispatcher (_plugin, effSetBlockSize, 0, _session.get_block_size(), NULL, 0.0f); } diff --git a/libs/ardour/windows_vst_plugin.cc b/libs/ardour/windows_vst_plugin.cc index 53bfee05e8..82304a9f93 100644 --- a/libs/ardour/windows_vst_plugin.cc +++ b/libs/ardour/windows_vst_plugin.cc @@ -39,9 +39,10 @@ WindowsVSTPlugin::WindowsVSTPlugin (AudioEngine& e, Session& session, VSTHandle* if ((_state = fst_instantiate (_handle, Session::vst_callback, this)) == 0) { throw failed_constructor(); } + open_plugin (); Session::vst_current_loading_id = 0; - set_plugin (_state->plugin); + init_plugin (); } WindowsVSTPlugin::WindowsVSTPlugin (const WindowsVSTPlugin &other) @@ -53,17 +54,16 @@ WindowsVSTPlugin::WindowsVSTPlugin (const WindowsVSTPlugin &other) if ((_state = fst_instantiate (_handle, Session::vst_callback, this)) == 0) { throw failed_constructor(); } + open_plugin (); Session::vst_current_loading_id = 0; - _plugin = _state->plugin; - XMLNode* root = new XMLNode (other.state_node_name ()); LocaleGuard lg; other.add_state (root); set_state (*root, Stateful::loading_state_version); delete root; - set_plugin (_state->plugin); + init_plugin (); } WindowsVSTPlugin::~WindowsVSTPlugin () diff --git a/libs/fst/vstwin.c b/libs/fst/vstwin.c index ec2f290cce..0668bbf033 100644 --- a/libs/fst/vstwin.c +++ b/libs/fst/vstwin.c @@ -550,8 +550,16 @@ fst_instantiate (VSTHandle* fhandle, audioMasterCallback amc, void* userptr) return NULL; } - fst->plugin->dispatcher (fst->plugin, effOpen, 0, 0, 0, 0); - fst->vst_version = fst->plugin->dispatcher (fst->plugin, effGetVstVersion, 0, 0, 0, 0); + if (!userptr) { + /* scanning.. or w/o master-callback userptr == 0, open now. + * + * Session::vst_callback needs a pointer to the AEffect + * ((VSTPlugin*)userptr)->_plugin = vstfx->plugin + * before calling effOpen, because effOpen may call back + */ + fst->plugin->dispatcher (fst->plugin, effOpen, 0, 0, 0, 0); + fst->vst_version = fst->plugin->dispatcher (fst->plugin, effGetVstVersion, 0, 0, 0, 0); + } fst->handle->plugincnt++; fst->wantIdle = 0; -- cgit v1.2.3