VST3: implement host/global IContextInfoProvider

This should fix crashes at instantiating sonible VST3
plugins.
This commit is contained in:
Robin Gareus
2025-08-25 22:21:19 +02:00
parent 0d03390976
commit 89c4fdc186
3 changed files with 92 additions and 2 deletions

View File

@@ -51,6 +51,10 @@ tresult PLUGIN_API queryInterface (const TUID _iid, void** obj) SMTG_OVERRIDE \
# pragma GCC diagnostic ignored "-Wdelete-non-virtual-dtor"
#endif
namespace ARDOUR {
class Session;
}
namespace Steinberg {
LIBARDOUR_API extern std::string tchar_to_utf8 (Vst::TChar const* s);
@@ -271,7 +275,7 @@ private:
std::vector<FUID> _interfaces;
};
class LIBARDOUR_API HostApplication : public Vst::IHostApplication
class LIBARDOUR_API HostApplication : public Vst::IHostApplication , public Presonus::IContextInfoProvider
{
public:
static Vst::IHostApplication* getHostContext ()
@@ -280,7 +284,10 @@ public:
return app;
}
HostApplication ();
static HostApplication* theHostContext () {
return static_cast<HostApplication*> (getHostContext ());
}
virtual ~HostApplication () {}
tresult PLUGIN_API queryInterface (const TUID _iid, void** obj) SMTG_OVERRIDE;
@@ -297,8 +304,17 @@ public:
tresult PLUGIN_API getName (Vst::String128 name) SMTG_OVERRIDE;
tresult PLUGIN_API createInstance (TUID cid, TUID _iid, void** obj) SMTG_OVERRIDE;
void set_session (ARDOUR::Session*);
/* IContextInfoProvider API */
tresult PLUGIN_API getContextInfoValue (int32&, FIDString) SMTG_OVERRIDE;
tresult PLUGIN_API getContextInfoString (Vst::TChar*, int32, FIDString) SMTG_OVERRIDE;
protected:
std::unique_ptr<PlugInterfaceSupport> _plug_interface_support;
private:
HostApplication ();
ARDOUR::Session* _session;
};
class LIBARDOUR_LOCAL Vst3ParamValueQueue : public Vst::IParamValueQueue

View File

@@ -138,6 +138,7 @@
#include "ardour/vca.h"
#ifdef VST3_SUPPORT
#include "ardour/vst3_host.h"
#include "ardour/vst3_plugin.h"
#endif // VST3_SUPPORT
@@ -541,6 +542,10 @@ Session::Session (AudioEngine &eng,
_engine.set_session (this);
_engine.reset_timebase ();
#ifdef VST3_SUPPORT
Steinberg::HostApplication::theHostContext ()->set_session (this);
#endif
if (!mix_template.empty ()) {
/* ::create() unsets _is_new after creating the session.
* But for templated sessions, the sample-rate is initially unset
@@ -909,6 +914,7 @@ Session::destroy ()
for (auto const& nfo : PluginManager::instance().vst3_plugin_info()) {
std::dynamic_pointer_cast<VST3PluginInfo> (nfo)->m.reset ();
}
Steinberg::HostApplication::theHostContext ()->set_session (0);
#endif // VST3_SUPPORT
DEBUG_TRACE (DEBUG::Destruction, "Session::destroy() done\n");

View File

@@ -20,6 +20,11 @@
#include <algorithm>
#include <ctype.h>
#ifndef VST3_SCANNER_APP
#include "ardour/session.h"
#include "ardour/session_directory.h"
#endif
#include "ardour/vst3_host.h"
#include "pbd/atomic.h"
@@ -610,6 +615,12 @@ PlugInterfaceSupport::addPlugInterfaceSupported (const TUID id)
HostApplication::HostApplication ()
{
_plug_interface_support.reset (new PlugInterfaceSupport);
_session = NULL;
}
void
HostApplication::set_session (ARDOUR::Session* s) {
_session = s;
}
tresult
@@ -630,6 +641,8 @@ HostApplication::queryInterface (const char* _iid, void** obj)
}
#if 1
QUERY_INTERFACE (_iid, obj, Presonus::IContextInfoProvider::iid, Presonus::IContextInfoProvider);
#else
/* Presonus specifies IContextInfoProvider as extension to IComponentHandler.
* However softube's console queries support for this during initialize()
* and tests host-application support.
@@ -679,6 +692,61 @@ HostApplication::createInstance (TUID cid, TUID _iid, void** obj)
/* ****************************************************************************/
tresult
HostApplication::getContextInfoValue (int32& value, FIDString id)
{
#ifdef VST3_SCANNER_APP
return kNotImplemented;
#else
if (0 == strcmp (id, Presonus::ContextInfo::kIndexMode)) {
value = Presonus::ContextInfo::kFlatIndex;
} else {
DEBUG_TRACE (PBD::DEBUG::VST3Callbacks, string_compose ("VST3Host::getContextInfoValue<int> unsupported ID %1\n", id));
return kNotImplemented;
}
DEBUG_TRACE (PBD::DEBUG::VST3Callbacks, string_compose ("VST3Host::getContextInfoValue<int> %1 = %2\n", id, value));
return kResultOk;
#endif
}
tresult
HostApplication::getContextInfoString (Vst::TChar* string, int32 max_len, FIDString id)
{
#ifdef VST3_SCANNER_APP
return kNotImplemented;
#else
using namespace Presonus;
if (!_session) {
DEBUG_TRACE (PBD::DEBUG::VST3Callbacks, string_compose ("VST3Host::setContextInfoString: NOT INITIALIZED (%1)\n", id));
return kNotInitialized;
}
if (0 == strcmp (id, ContextInfo::kDocumentID)) {
DEBUG_TRACE (PBD::DEBUG::VST3Callbacks, string_compose ("VST3Host::setContextInfoString: NOT IMPLEMENTED (%1)\n", id));
return kNotImplemented; // XXX TODO
} else if (0 == strcmp (id, ContextInfo::kActiveDocumentID)) {
DEBUG_TRACE (PBD::DEBUG::VST3Callbacks, string_compose ("VST3Host::setContextInfoString: NOT IMPLEMENTED (%1)\n", id));
return kNotImplemented; // XXX TODO
} else if (0 == strcmp (id, ContextInfo::kDocumentID)) {
DEBUG_TRACE (PBD::DEBUG::VST3Callbacks, string_compose ("VST3Host::setContextInfoString: NOT IMPLEMENTED (%1)\n", id));
return kNotImplemented; // XXX TODO
} else if (0 == strcmp (id, ContextInfo::kDocumentName)) {
utf8_to_tchar (string, _session->name(), max_len);
} else if (0 == strcmp (id, ContextInfo::kDocumentFolder)) {
utf8_to_tchar (string, _session->path(), max_len);
} else if (0 == strcmp (id, ContextInfo::kAudioFolder)) {
utf8_to_tchar (string, _session->session_directory().sound_path(), max_len);
} else {
DEBUG_TRACE (PBD::DEBUG::VST3Callbacks, string_compose ("VST3Host::getContextInfoString unsupported ID %1\n", id));
return kInvalidArgument;
}
DEBUG_TRACE (PBD::DEBUG::VST3Callbacks, string_compose ("VST3Host::getContextInfoValue<string> %1 = %2\n", id, tchar_to_utf8 (string)));
return kResultOk;
#endif
}
/* ****************************************************************************/
tresult
Vst3ParamValueQueue::getPoint (int32 index, int32& sampleOffset, Vst::ParamValue& value)
{