Rename the monolitic class to Vst3PluginProxy

Now it's starting to look promising.
This commit is contained in:
Robbert van der Helm
2020-12-17 13:07:42 +01:00
parent d8b2646563
commit 11bf7532fa
21 changed files with 352 additions and 354 deletions
+3 -3
View File
@@ -4,10 +4,10 @@ TODO: Flesh this out further
TODO: Link to `src/common/serialization/vst3/README.md` TODO: Link to `src/common/serialization/vst3/README.md`
TODO: Mention the new `Ya<Base>::supports()` mechanism for monolithic interfaces TODO: Mention the new `Ya<Base>::supports()` mechanism for the monolithic proxy
through multiple inheritance objects through multiple inheritance
TODO: Explain the monolith. TODO: Explain the monolith
The VST3 SDK uses an architecture where every concrete object inherits from an The VST3 SDK uses an architecture where every concrete object inherits from an
interface, and every interface inherits from `FUnknown`. `FUnkonwn` offers a interface, and every interface inherits from `FUnknown`. `FUnkonwn` offers a
+3 -3
View File
@@ -85,15 +85,15 @@ vst3_plugin_sources = [
'src/common/serialization/vst3/param-value-queue.cpp', 'src/common/serialization/vst3/param-value-queue.cpp',
'src/common/serialization/vst3/parameter-changes.cpp', 'src/common/serialization/vst3/parameter-changes.cpp',
'src/common/serialization/vst3/plugin-base.cpp', 'src/common/serialization/vst3/plugin-base.cpp',
'src/common/serialization/vst3/plugin-monolith.cpp', 'src/common/serialization/vst3/plugin-proxy.cpp',
'src/common/serialization/vst3/plugin-factory.cpp', 'src/common/serialization/vst3/plugin-factory.cpp',
'src/common/serialization/vst3/process-data.cpp', 'src/common/serialization/vst3/process-data.cpp',
'src/common/configuration.cpp', 'src/common/configuration.cpp',
'src/common/plugins.cpp', 'src/common/plugins.cpp',
'src/common/utils.cpp', 'src/common/utils.cpp',
'src/plugin/bridges/vst3.cpp', 'src/plugin/bridges/vst3.cpp',
'src/plugin/bridges/vst3-impls/component.cpp',
'src/plugin/bridges/vst3-impls/plugin-factory.cpp', 'src/plugin/bridges/vst3-impls/plugin-factory.cpp',
'src/plugin/bridges/vst3-impls/plugin-proxy.cpp',
'src/plugin/host-process.cpp', 'src/plugin/host-process.cpp',
'src/plugin/utils.cpp', 'src/plugin/utils.cpp',
'src/plugin/vst3-plugin.cpp', 'src/plugin/vst3-plugin.cpp',
@@ -127,7 +127,7 @@ if with_vst3
'src/common/serialization/vst3/param-value-queue.cpp', 'src/common/serialization/vst3/param-value-queue.cpp',
'src/common/serialization/vst3/parameter-changes.cpp', 'src/common/serialization/vst3/parameter-changes.cpp',
'src/common/serialization/vst3/plugin-base.cpp', 'src/common/serialization/vst3/plugin-base.cpp',
'src/common/serialization/vst3/plugin-monolith.cpp', 'src/common/serialization/vst3/plugin-proxy.cpp',
'src/common/serialization/vst3/plugin-factory.cpp', 'src/common/serialization/vst3/plugin-factory.cpp',
'src/common/serialization/vst3/process-data.cpp', 'src/common/serialization/vst3/process-data.cpp',
'src/wine-host/bridges/vst3-impls/host-application.cpp', 'src/wine-host/bridges/vst3-impls/host-application.cpp',
+10 -9
View File
@@ -37,7 +37,7 @@ void Vst3Logger::log_unknown_interface(
} }
void Vst3Logger::log_request(bool is_host_vst, void Vst3Logger::log_request(bool is_host_vst,
const YaPluginMonolith::Construct&) { const Vst3PluginProxy::Construct&) {
log_request_base(is_host_vst, [&](auto& message) { log_request_base(is_host_vst, [&](auto& message) {
// TODO: Log the CID on verbosity level 2, and then also report all CIDs // TODO: Log the CID on verbosity level 2, and then also report all CIDs
// in the plugin factory // in the plugin factory
@@ -51,7 +51,7 @@ void Vst3Logger::log_request(bool is_host_vst,
} }
void Vst3Logger::log_request(bool is_host_vst, void Vst3Logger::log_request(bool is_host_vst,
const YaPluginMonolith::Destruct& request) { const Vst3PluginProxy::Destruct& request) {
log_request_base(is_host_vst, [&](auto& message) { log_request_base(is_host_vst, [&](auto& message) {
message << "<IComponent* #" << request.instance_id message << "<IComponent* #" << request.instance_id
<< ">::~IComponent()"; << ">::~IComponent()";
@@ -70,7 +70,8 @@ void Vst3Logger::log_request(
}); });
} }
void Vst3Logger::log_request(bool is_host_vst, void Vst3Logger::log_request(
bool is_host_vst,
const YaAudioProcessor::GetBusArrangement& request) { const YaAudioProcessor::GetBusArrangement& request) {
log_request_base(is_host_vst, [&](auto& message) { log_request_base(is_host_vst, [&](auto& message) {
message << "<IAudioProcessor* #" << request.instance_id message << "<IAudioProcessor* #" << request.instance_id
@@ -79,7 +80,8 @@ void Vst3Logger::log_request(bool is_host_vst,
}); });
} }
void Vst3Logger::log_request(bool is_host_vst, void Vst3Logger::log_request(
bool is_host_vst,
const YaAudioProcessor::CanProcessSampleSize& request) { const YaAudioProcessor::CanProcessSampleSize& request) {
log_request_base(is_host_vst, [&](auto& message) { log_request_base(is_host_vst, [&](auto& message) {
message << "<IAudioProcessor* #" << request.instance_id message << "<IAudioProcessor* #" << request.instance_id
@@ -256,12 +258,11 @@ void Vst3Logger::log_response(bool is_host_vst, const Ack&) {
log_response_base(is_host_vst, [&](auto& message) { message << "ACK"; }); log_response_base(is_host_vst, [&](auto& message) { message << "ACK"; });
} }
void Vst3Logger::log_response( void Vst3Logger::log_response(bool is_host_vst,
bool is_host_vst, const std::variant<Vst3PluginProxy::ConstructArgs,
const std::variant<YaPluginMonolith::ConstructArgs, UniversalTResult>& UniversalTResult>& result) {
result) {
log_response_base(is_host_vst, [&](auto& message) { log_response_base(is_host_vst, [&](auto& message) {
std::visit(overload{[&](const YaPluginMonolith::ConstructArgs& args) { std::visit(overload{[&](const Vst3PluginProxy::ConstructArgs& args) {
message << "<IComponent* #" << args.instance_id message << "<IComponent* #" << args.instance_id
<< ">"; << ">";
}, },
+3 -3
View File
@@ -56,8 +56,8 @@ class Vst3Logger {
// flag here indicates whether the request was initiated on the host side // flag here indicates whether the request was initiated on the host side
// (what we'll call a control message). // (what we'll call a control message).
void log_request(bool is_host_vst, const YaPluginMonolith::Construct&); void log_request(bool is_host_vst, const Vst3PluginProxy::Construct&);
void log_request(bool is_host_vst, const YaPluginMonolith::Destruct&); void log_request(bool is_host_vst, const Vst3PluginProxy::Destruct&);
void log_request(bool is_host_vst, void log_request(bool is_host_vst,
const YaAudioProcessor::SetBusArrangements&); const YaAudioProcessor::SetBusArrangements&);
void log_request(bool is_host_vst, void log_request(bool is_host_vst,
@@ -88,7 +88,7 @@ class Vst3Logger {
void log_response(bool is_host_vst, const Ack&); void log_response(bool is_host_vst, const Ack&);
void log_response( void log_response(
bool is_host_vst, bool is_host_vst,
const std::variant<YaPluginMonolith::ConstructArgs, UniversalTResult>&); const std::variant<Vst3PluginProxy::ConstructArgs, UniversalTResult>&);
void log_response(bool is_host_vst, void log_response(bool is_host_vst,
const YaAudioProcessor::GetBusArrangementResponse&); const YaAudioProcessor::GetBusArrangementResponse&);
void log_response(bool is_host_vst, void log_response(bool is_host_vst,
+3 -3
View File
@@ -24,7 +24,7 @@
#include "../utils.h" #include "../utils.h"
#include "common.h" #include "common.h"
#include "vst3/plugin-factory.h" #include "vst3/plugin-factory.h"
#include "vst3/plugin-monolith.h" #include "vst3/plugin-proxy.h"
// Event handling for our VST3 plugins works slightly different from how we // Event handling for our VST3 plugins works slightly different from how we
// handle VST2 plugins. VST3 does not have a centralized event dispatching // handle VST2 plugins. VST3 does not have a centralized event dispatching
@@ -57,8 +57,8 @@ struct WantsConfiguration {
* encodes the information we request or the operation we want to perform. A * encodes the information we request or the operation we want to perform. A
* request of type `ControlRequest(T)` should send back a `T::Response`. * request of type `ControlRequest(T)` should send back a `T::Response`.
*/ */
using ControlRequest = std::variant<YaPluginMonolith::Construct, using ControlRequest = std::variant<Vst3PluginProxy::Construct,
YaPluginMonolith::Destruct, Vst3PluginProxy::Destruct,
YaAudioProcessor::SetBusArrangements, YaAudioProcessor::SetBusArrangements,
YaAudioProcessor::GetBusArrangement, YaAudioProcessor::GetBusArrangement,
YaAudioProcessor::CanProcessSampleSize, YaAudioProcessor::CanProcessSampleSize,
+5 -5
View File
@@ -8,11 +8,11 @@ serialization works.
VST3 interfaces are implemented as follows: VST3 interfaces are implemented as follows:
| Yabridge class | Included in | Interfaces | | Yabridge class | Included in | Interfaces |
| ------------------- | ------------------ | ------------------------------------------------------ | | ------------------- | ----------------- | ------------------------------------------------------ |
| `YaPluginMonolith` | | All of the below | | `Vst3PluginProxy` | | All of the below: |
| `YaAudioProcessor` | `YaPluginMonolith` | `IAudioProcessor` | | `YaAudioProcessor` | `Vst3PluginProxy` | `IAudioProcessor` |
| `YaComponent` | `YaPluginMonolith` | `IComponent` | | `YaComponent` | `Vst3PluginProxy` | `IComponent` |
| `YaPluginBase` | `YaPluginMonolith` | `IPluginBase` | | `YaPluginBase` | `Vst3PluginProxy` | `IPluginBase` |
| `YaHostApplication` | | `iHostAPplication` | | `YaHostApplication` | | `iHostAPplication` |
| `YaPluginFactory` | | `IPluginFactory`, `IPluginFactory2`, `IPluginFactory3` | | `YaPluginFactory` | | `IPluginFactory`, `IPluginFactory2`, `IPluginFactory3` |
@@ -29,7 +29,7 @@
/** /**
* Wraps around `IAudioProcessor` for serialization purposes. This is * Wraps around `IAudioProcessor` for serialization purposes. This is
* instantiated as part of `YaPluginMonolith`. * instantiated as part of `Vst3PluginProxy`.
*/ */
class YaAudioProcessor : public Steinberg::Vst::IAudioProcessor { class YaAudioProcessor : public Steinberg::Vst::IAudioProcessor {
public: public:
+1 -1
View File
@@ -29,7 +29,7 @@
/** /**
* Wraps around `IComponent` for serialization purposes. This is instantiated as * Wraps around `IComponent` for serialization purposes. This is instantiated as
* part of `YaPluginMonolith`. Event though `IComponent` inherits from * part of `Vst3PluginProxy`. Event though `IComponent` inherits from
* `IPlguinBase`, we'll implement that separately in `YaPluginBase` because * `IPlguinBase`, we'll implement that separately in `YaPluginBase` because
* `IEditController` also inherits from `IPluginBase`. * `IEditController` also inherits from `IPluginBase`.
*/ */
@@ -36,7 +36,7 @@
* both the native plugin side as well as the Wine plugin host side. * both the native plugin side as well as the Wine plugin host side.
* *
* TODO: When implementing more host interfaces, also rework this into a * TODO: When implementing more host interfaces, also rework this into a
* monolith class like with the plugin. * monolithic proxy class like with the plugin.
*/ */
class YaHostApplication : public Steinberg::Vst::IHostApplication { class YaHostApplication : public Steinberg::Vst::IHostApplication {
public: public:
+1 -1
View File
@@ -29,7 +29,7 @@
/** /**
* Wraps around `IPluginBase` for serialization purposes. Both components and * Wraps around `IPluginBase` for serialization purposes. Both components and
* edit controllers inherit from this. This is instantiated as part of * edit controllers inherit from this. This is instantiated as part of
* `YaPluginMonolith`. * `Vst3PluginProxy`.
*/ */
class YaPluginBase : public Steinberg::IPluginBase { class YaPluginBase : public Steinberg::IPluginBase {
public: public:
+1 -151
View File
@@ -1,151 +1 @@
// yabridge: a Wine VST bridge Vst3PluginProxyVst3PluginProxyVst3PluginProxyVst3PluginProxy
// Copyright (C) 2020 Robbert van der Helm
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
#pragma once
#include <bitsery/ext/std_variant.h>
#include <pluginterfaces/vst/ivstcomponent.h>
#include "../common.h"
#include "audio-processor.h"
#include "base.h"
#include "component.h"
#include "host-application.h"
#include "plugin-base.h"
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wnon-virtual-dtor"
/**
* An abstract class that optionally implements all VST3 interfaces a plugin
* object could implement. A more in depth explanation can be found in
* `docs/vst3.md`, but the way this works is that we begin with an `FUnknown`
* pointer from the Windows VST3 plugin obtained by a call to
* `IPluginFactory::createInstance()` (with an interface decided by the host).
* We then go through all the plugin interfaces and check whether that object
* supports them one by one. For each supported interface we remember that the
* plugin supports it, and we'll optionally write down some static data (such as
* the edit controller cid) that can't change over the lifetime of the
* application. On the plugin side we then return a `YaPluginMonolith`
* implementation that contains all of this information about interfaces the
* object we're proxying might support. This way we can allow casts to all of
* those object types in `queryInterface()`, essentially perfectly mimicing the
* original object.
*
* This monolith approach is also important when it comes to `IConnectionPoint`.
* The host should be able to connect arbitrary objects together, and the plugin
* can then use the query interface smart pointer casting system to cast those
* objects to the types they want. By having a huge monolithic class that
* implements any interface such an object might also implement, we can allow
* perfect proxying behaviour for connecting components.
*/
class YaPluginMonolith : public YaAudioProcessor,
public YaComponent,
public YaPluginBase {
public:
/**
* These are the arguments for creating a `YaPluginMonolithImpl`.
*/
struct ConstructArgs {
ConstructArgs();
/**
* Read from an existing object. We will try to mimic this object, so
* we'll support any interfaces this object also supports.
*/
ConstructArgs(Steinberg::IPtr<FUnknown> object, size_t instance_id);
/**
* The unique identifier for this specific object instance.
*/
native_size_t instance_id;
YaAudioProcessor::ConstructArgs audio_processor_args;
YaComponent::ConstructArgs component_args;
YaPluginBase::ConstructArgs plugin_base_args;
template <typename S>
void serialize(S& s) {
s.value8b(instance_id);
s.object(audio_processor_args);
s.object(component_args);
s.object(plugin_base_args);
}
};
/**
* Message to request the Wine plugin host to instantiate a new IComponent
* to pass through a call to `IComponent::createInstance(cid,
* IComponent::iid, ...)`.
*/
struct Construct {
using Response = std::variant<ConstructArgs, UniversalTResult>;
ArrayUID cid;
// TODO: Add an enum class to reify the type of object we want to
// instantiate so we can initialize things other than
// `IComponent`, like `IEditController.`
template <typename S>
void serialize(S& s) {
s.container1b(cid);
}
};
/**
* Instantiate this object instance with arguments read from another
* interface implementation.
*/
YaPluginMonolith(const ConstructArgs&& args);
/**
* Message to request the Wine plugin host to destroy this object instance
* with the given instance ID. Sent from the destructor of
* `YaPluginMonolithImpl`. This will cause all smart pointers to the actual
* object in the Wine plugin host to be dropped.
*/
struct Destruct {
using Response = Ack;
native_size_t instance_id;
template <typename S>
void serialize(S& s) {
s.value8b(instance_id);
}
};
/**
* @remark The plugin side implementation should send a control message to
* clean up the instance on the Wine side in its destructor.
*/
virtual ~YaPluginMonolith() = 0;
DECLARE_FUNKNOWN_METHODS
protected:
ConstructArgs arguments;
};
#pragma GCC diagnostic pop
template <typename S>
void serialize(
S& s,
std::variant<YaPluginMonolith::ConstructArgs, UniversalTResult>& result) {
s.ext(result, bitsery::ext::StdVariant{});
}
@@ -14,11 +14,11 @@
// You should have received a copy of the GNU General Public License // You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>. // along with this program. If not, see <https://www.gnu.org/licenses/>.
#include "plugin-monolith.h" #include "plugin-proxy.h"
YaPluginMonolith::ConstructArgs::ConstructArgs() {} Vst3PluginProxy::ConstructArgs::ConstructArgs() {}
YaPluginMonolith::ConstructArgs::ConstructArgs( Vst3PluginProxy::ConstructArgs::ConstructArgs(
Steinberg::IPtr<Steinberg::FUnknown> object, Steinberg::IPtr<Steinberg::FUnknown> object,
size_t instance_id) size_t instance_id)
: instance_id(instance_id), : instance_id(instance_id),
@@ -26,22 +26,22 @@ YaPluginMonolith::ConstructArgs::ConstructArgs(
component_args(object), component_args(object),
plugin_base_args(object) {} plugin_base_args(object) {}
YaPluginMonolith::YaPluginMonolith(const ConstructArgs&& args) Vst3PluginProxy::Vst3PluginProxy(const ConstructArgs&& args)
: YaAudioProcessor(std::move(args.audio_processor_args)), : YaAudioProcessor(std::move(args.audio_processor_args)),
YaComponent(std::move(args.component_args)), YaComponent(std::move(args.component_args)),
YaPluginBase(std::move(args.plugin_base_args)), YaPluginBase(std::move(args.plugin_base_args)),
arguments(std::move(args)){FUNKNOWN_CTOR} arguments(std::move(args)){FUNKNOWN_CTOR}
YaPluginMonolith::~YaPluginMonolith() { Vst3PluginProxy::~Vst3PluginProxy() {
FUNKNOWN_DTOR FUNKNOWN_DTOR
} }
#pragma GCC diagnostic push #pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wdelete-non-virtual-dtor" #pragma GCC diagnostic ignored "-Wdelete-non-virtual-dtor"
IMPLEMENT_REFCOUNT(YaPluginMonolith) IMPLEMENT_REFCOUNT(Vst3PluginProxy)
#pragma GCC diagnostic pop #pragma GCC diagnostic pop
tresult PLUGIN_API YaPluginMonolith::queryInterface(Steinberg::FIDString _iid, tresult PLUGIN_API Vst3PluginProxy::queryInterface(Steinberg::FIDString _iid,
void** obj) { void** obj) {
if (YaPluginBase::supported()) { if (YaPluginBase::supported()) {
// We had to expand the macro here because we need to cast through // We had to expand the macro here because we need to cast through
@@ -0,0 +1,151 @@
// yabridge: a Wine VST bridge
// Copyright (C) 2020 Robbert van der Helm
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
#pragma once
#include <bitsery/ext/std_variant.h>
#include <pluginterfaces/vst/ivstcomponent.h>
#include "../common.h"
#include "audio-processor.h"
#include "base.h"
#include "component.h"
#include "host-application.h"
#include "plugin-base.h"
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wnon-virtual-dtor"
/**
* An abstract class that optionally implements all VST3 interfaces a plugin
* object could implement. A more in depth explanation can be found in
* `docs/vst3.md`, but the way this works is that we begin with an `FUnknown`
* pointer from the Windows VST3 plugin obtained by a call to
* `IPluginFactory::createInstance()` (with an interface decided by the host).
* We then go through all the plugin interfaces and check whether that object
* supports them one by one. For each supported interface we remember that the
* plugin supports it, and we'll optionally write down some static data (such as
* the edit controller cid) that can't change over the lifetime of the
* application. On the plugin side we then return a `Vst3PluginProxyImpl` object
* that contains all of this information about interfaces the object we're
* proxying might support. This way we can allow casts to all of those object
* types in `queryInterface()`, essentially perfectly mimicing the original
* object.
*
* This monolith approach is also important when it comes to `IConnectionPoint`.
* The host should be able to connect arbitrary objects together, and the plugin
* can then use the query interface smart pointer casting system to cast those
* objects to the types they want. By having a huge monolithic class that
* implements any interface such an object might also implement, we can allow
* perfect proxying behaviour for connecting components.
*/
class Vst3PluginProxy : public YaAudioProcessor,
public YaComponent,
public YaPluginBase {
public:
/**
* These are the arguments for creating a `Vst3PluginProxyImpl`.
*/
struct ConstructArgs {
ConstructArgs();
/**
* Read from an existing object. We will try to mimic this object, so
* we'll support any interfaces this object also supports.
*/
ConstructArgs(Steinberg::IPtr<FUnknown> object, size_t instance_id);
/**
* The unique identifier for this specific object instance.
*/
native_size_t instance_id;
YaAudioProcessor::ConstructArgs audio_processor_args;
YaComponent::ConstructArgs component_args;
YaPluginBase::ConstructArgs plugin_base_args;
template <typename S>
void serialize(S& s) {
s.value8b(instance_id);
s.object(audio_processor_args);
s.object(component_args);
s.object(plugin_base_args);
}
};
/**
* Message to request the Wine plugin host to instantiate a new IComponent
* to pass through a call to `IComponent::createInstance(cid,
* IComponent::iid, ...)`.
*/
struct Construct {
using Response = std::variant<ConstructArgs, UniversalTResult>;
ArrayUID cid;
// TODO: Add an enum class to reify the type of object we want to
// instantiate so we can initialize things other than
// `IComponent`, like `IEditController.`
template <typename S>
void serialize(S& s) {
s.container1b(cid);
}
};
/**
* Instantiate this object instance with arguments read from another
* interface implementation.
*/
Vst3PluginProxy(const ConstructArgs&& args);
/**
* Message to request the Wine plugin host to destroy this object instance
* with the given instance ID. Sent from the destructor of
* `Vst3PluginProxyImpl`. This will cause all smart pointers to the actual
* object in the Wine plugin host to be dropped.
*/
struct Destruct {
using Response = Ack;
native_size_t instance_id;
template <typename S>
void serialize(S& s) {
s.value8b(instance_id);
}
};
/**
* @remark The plugin side implementation should send a control message to
* clean up the instance on the Wine side in its destructor.
*/
virtual ~Vst3PluginProxy() = 0;
DECLARE_FUNKNOWN_METHODS
protected:
ConstructArgs arguments;
};
#pragma GCC diagnostic pop
template <typename S>
void serialize(
S& s,
std::variant<Vst3PluginProxy::ConstructArgs, UniversalTResult>& result) {
s.ext(result, bitsery::ext::StdVariant{});
}
+1 -95
View File
@@ -1,95 +1 @@
// yabridge: a Wine VST bridge YaPluginProxyImplYaPluginProxyImplYaPluginProxyImpl
// Copyright (C) 2020 Robbert van der Helm
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
#pragma once
#include <pluginterfaces/vst/ivsthostapplication.h>
#include "../vst3.h"
class YaPluginMonolithImpl : public YaPluginMonolith {
public:
YaPluginMonolithImpl(Vst3PluginBridge& bridge,
YaPluginMonolith::ConstructArgs&& args);
/**
* When the reference count reaches zero and this destructor is called,
* we'll send a request to the Wine plugin host to destroy the corresponding
* object.
*/
~YaPluginMonolithImpl();
/**
* We'll override the query interface to log queries for interfaces we do
* not (yet) support.
*/
tresult PLUGIN_API queryInterface(const Steinberg::TUID _iid,
void** obj) override;
// From `IAudioProcessor`
tresult PLUGIN_API
setBusArrangements(Steinberg::Vst::SpeakerArrangement* inputs,
int32 numIns,
Steinberg::Vst::SpeakerArrangement* outputs,
int32 numOuts) override;
tresult PLUGIN_API
getBusArrangement(Steinberg::Vst::BusDirection dir,
int32 index,
Steinberg::Vst::SpeakerArrangement& arr) override;
tresult PLUGIN_API canProcessSampleSize(int32 symbolicSampleSize) override;
uint32 PLUGIN_API getLatencySamples() override;
tresult PLUGIN_API
setupProcessing(Steinberg::Vst::ProcessSetup& setup) override;
tresult PLUGIN_API setProcessing(TBool state) override;
tresult PLUGIN_API process(Steinberg::Vst::ProcessData& data) override;
uint32 PLUGIN_API getTailSamples() override;
// From `IComponent`
tresult PLUGIN_API setIoMode(Steinberg::Vst::IoMode mode) override;
int32 PLUGIN_API getBusCount(Steinberg::Vst::MediaType type,
Steinberg::Vst::BusDirection dir) override;
tresult PLUGIN_API
getBusInfo(Steinberg::Vst::MediaType type,
Steinberg::Vst::BusDirection dir,
int32 index,
Steinberg::Vst::BusInfo& bus /*out*/) override;
tresult PLUGIN_API
getRoutingInfo(Steinberg::Vst::RoutingInfo& inInfo,
Steinberg::Vst::RoutingInfo& outInfo /*out*/) override;
tresult PLUGIN_API activateBus(Steinberg::Vst::MediaType type,
Steinberg::Vst::BusDirection dir,
int32 index,
TBool state) override;
tresult PLUGIN_API setActive(TBool state) override;
tresult PLUGIN_API setState(Steinberg::IBStream* state) override;
tresult PLUGIN_API getState(Steinberg::IBStream* state) override;
// From `IPluginBase`
tresult PLUGIN_API initialize(FUnknown* context) override;
tresult PLUGIN_API terminate() override;
private:
Vst3PluginBridge& bridge;
/**
* An `IHostApplication` instance if we get one through
* `IPluginBase::initialize()`. This should be the same for all plugin
* instances so we should not have to store it here separately, but for the
* sake of correctness we will.
*/
Steinberg::FUnknownPtr<Steinberg::Vst::IHostApplication>
host_application_context;
};
@@ -18,15 +18,14 @@
#include <pluginterfaces/vst/ivstcomponent.h> #include <pluginterfaces/vst/ivstcomponent.h>
#include "component.h" #include "plugin-proxy.h"
YaPluginFactoryPluginImpl::YaPluginFactoryPluginImpl( YaPluginFactoryImpl::YaPluginFactoryImpl(Vst3PluginBridge& bridge,
Vst3PluginBridge& bridge,
YaPluginFactory::ConstructArgs&& args) YaPluginFactory::ConstructArgs&& args)
: YaPluginFactory(std::move(args)), bridge(bridge) {} : YaPluginFactory(std::move(args)), bridge(bridge) {}
tresult PLUGIN_API tresult PLUGIN_API
YaPluginFactoryPluginImpl::createInstance(Steinberg::FIDString cid, YaPluginFactoryImpl::createInstance(Steinberg::FIDString cid,
Steinberg::FIDString _iid, Steinberg::FIDString _iid,
void** obj) { void** obj) {
// TODO: Do the same thing for other types // TODO: Do the same thing for other types
@@ -38,13 +37,13 @@ YaPluginFactoryPluginImpl::createInstance(Steinberg::FIDString cid,
ArrayUID cid_array; ArrayUID cid_array;
std::copy(cid, cid + sizeof(Steinberg::TUID), cid_array.begin()); std::copy(cid, cid + sizeof(Steinberg::TUID), cid_array.begin());
if (Steinberg::FIDStringsEqual(_iid, Steinberg::Vst::IComponent::iid)) { if (Steinberg::FIDStringsEqual(_iid, Steinberg::Vst::IComponent::iid)) {
std::variant<YaPluginMonolith::ConstructArgs, UniversalTResult> result = std::variant<Vst3PluginProxy::ConstructArgs, UniversalTResult> result =
bridge.send_message(YaPluginMonolith::Construct{.cid = cid_array}); bridge.send_message(Vst3PluginProxy::Construct{.cid = cid_array});
return std::visit( return std::visit(
overload{ overload{
[&](YaPluginMonolith::ConstructArgs&& args) -> tresult { [&](Vst3PluginProxy::ConstructArgs&& args) -> tresult {
*obj = static_cast<Steinberg::Vst::IComponent*>( *obj = static_cast<Steinberg::Vst::IComponent*>(
new YaPluginMonolithImpl(bridge, std::move(args))); new Vst3PluginProxyImpl(bridge, std::move(args)));
return Steinberg::kResultOk; return Steinberg::kResultOk;
}, },
[&](const UniversalTResult& code) -> tresult { return code; }}, [&](const UniversalTResult& code) -> tresult { return code; }},
@@ -69,7 +68,7 @@ YaPluginFactoryPluginImpl::createInstance(Steinberg::FIDString cid,
} }
tresult PLUGIN_API tresult PLUGIN_API
YaPluginFactoryPluginImpl::setHostContext(Steinberg::FUnknown* context) { YaPluginFactoryImpl::setHostContext(Steinberg::FUnknown* context) {
// This `context` will likely be an `IHostApplication`. If it is, we will // This `context` will likely be an `IHostApplication`. If it is, we will
// store it for future calls, create a proxy object on the Wine side, and // store it for future calls, create a proxy object on the Wine side, and
// then pass it to the Windows VST3 plugin's plugin factory using the same // then pass it to the Windows VST3 plugin's plugin factory using the same
@@ -18,10 +18,9 @@
#include "../vst3.h" #include "../vst3.h"
// TODO Rename to YaPluginFactoryImpl class YaPluginFactoryImpl : public YaPluginFactory {
class YaPluginFactoryPluginImpl : public YaPluginFactory {
public: public:
YaPluginFactoryPluginImpl(Vst3PluginBridge& bridge, YaPluginFactoryImpl(Vst3PluginBridge& bridge,
YaPluginFactory::ConstructArgs&& args); YaPluginFactory::ConstructArgs&& args);
tresult PLUGIN_API createInstance(Steinberg::FIDString cid, tresult PLUGIN_API createInstance(Steinberg::FIDString cid,
@@ -14,25 +14,24 @@
// You should have received a copy of the GNU General Public License // You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>. // along with this program. If not, see <https://www.gnu.org/licenses/>.
#include "component.h" #include "plugin-proxy.h"
YaPluginMonolithImpl::YaPluginMonolithImpl( Vst3PluginProxyImpl::Vst3PluginProxyImpl(Vst3PluginBridge& bridge,
Vst3PluginBridge& bridge, Vst3PluginProxy::ConstructArgs&& args)
YaPluginMonolith::ConstructArgs&& args) : Vst3PluginProxy(std::move(args)), bridge(bridge) {
: YaPluginMonolith(std::move(args)), bridge(bridge) {
bridge.register_component(arguments.instance_id, *this); bridge.register_component(arguments.instance_id, *this);
} }
YaPluginMonolithImpl::~YaPluginMonolithImpl() { Vst3PluginProxyImpl::~Vst3PluginProxyImpl() {
bridge.send_message( bridge.send_message(
YaPluginMonolith::Destruct{.instance_id = arguments.instance_id}); Vst3PluginProxy::Destruct{.instance_id = arguments.instance_id});
bridge.unregister_component(arguments.instance_id); bridge.unregister_component(arguments.instance_id);
} }
tresult PLUGIN_API tresult PLUGIN_API
YaPluginMonolithImpl::queryInterface(const Steinberg::TUID _iid, void** obj) { Vst3PluginProxyImpl::queryInterface(const Steinberg::TUID _iid, void** obj) {
// TODO: Successful queries should also be logged // TODO: Successful queries should also be logged
const tresult result = YaPluginMonolith::queryInterface(_iid, obj); const tresult result = Vst3PluginProxy::queryInterface(_iid, obj);
if (result != Steinberg::kResultOk) { if (result != Steinberg::kResultOk) {
bridge.logger.log_unknown_interface("In IComponent::queryInterface()", bridge.logger.log_unknown_interface("In IComponent::queryInterface()",
Steinberg::FUID::fromTUID(_iid)); Steinberg::FUID::fromTUID(_iid));
@@ -41,7 +40,7 @@ YaPluginMonolithImpl::queryInterface(const Steinberg::TUID _iid, void** obj) {
return result; return result;
} }
tresult PLUGIN_API YaPluginMonolithImpl::setBusArrangements( tresult PLUGIN_API Vst3PluginProxyImpl::setBusArrangements(
Steinberg::Vst::SpeakerArrangement* inputs, Steinberg::Vst::SpeakerArrangement* inputs,
int32 numIns, int32 numIns,
Steinberg::Vst::SpeakerArrangement* outputs, Steinberg::Vst::SpeakerArrangement* outputs,
@@ -58,7 +57,7 @@ tresult PLUGIN_API YaPluginMonolithImpl::setBusArrangements(
}); });
} }
tresult PLUGIN_API YaPluginMonolithImpl::getBusArrangement( tresult PLUGIN_API Vst3PluginProxyImpl::getBusArrangement(
Steinberg::Vst::BusDirection dir, Steinberg::Vst::BusDirection dir,
int32 index, int32 index,
Steinberg::Vst::SpeakerArrangement& arr) { Steinberg::Vst::SpeakerArrangement& arr) {
@@ -75,30 +74,30 @@ tresult PLUGIN_API YaPluginMonolithImpl::getBusArrangement(
} }
tresult PLUGIN_API tresult PLUGIN_API
YaPluginMonolithImpl::canProcessSampleSize(int32 symbolicSampleSize) { Vst3PluginProxyImpl::canProcessSampleSize(int32 symbolicSampleSize) {
return bridge.send_message(YaAudioProcessor::CanProcessSampleSize{ return bridge.send_message(YaAudioProcessor::CanProcessSampleSize{
.instance_id = arguments.instance_id, .instance_id = arguments.instance_id,
.symbolic_sample_size = symbolicSampleSize}); .symbolic_sample_size = symbolicSampleSize});
} }
uint32 PLUGIN_API YaPluginMonolithImpl::getLatencySamples() { uint32 PLUGIN_API Vst3PluginProxyImpl::getLatencySamples() {
return bridge.send_message(YaAudioProcessor::GetLatencySamples{ return bridge.send_message(YaAudioProcessor::GetLatencySamples{
.instance_id = arguments.instance_id}); .instance_id = arguments.instance_id});
} }
tresult PLUGIN_API tresult PLUGIN_API
YaPluginMonolithImpl::setupProcessing(Steinberg::Vst::ProcessSetup& setup) { Vst3PluginProxyImpl::setupProcessing(Steinberg::Vst::ProcessSetup& setup) {
return bridge.send_message(YaAudioProcessor::SetupProcessing{ return bridge.send_message(YaAudioProcessor::SetupProcessing{
.instance_id = arguments.instance_id, .setup = setup}); .instance_id = arguments.instance_id, .setup = setup});
} }
tresult PLUGIN_API YaPluginMonolithImpl::setProcessing(TBool state) { tresult PLUGIN_API Vst3PluginProxyImpl::setProcessing(TBool state) {
return bridge.send_message(YaAudioProcessor::SetProcessing{ return bridge.send_message(YaAudioProcessor::SetProcessing{
.instance_id = arguments.instance_id, .state = state}); .instance_id = arguments.instance_id, .state = state});
} }
tresult PLUGIN_API tresult PLUGIN_API
YaPluginMonolithImpl::process(Steinberg::Vst::ProcessData& data) { Vst3PluginProxyImpl::process(Steinberg::Vst::ProcessData& data) {
ProcessResponse response = bridge.send_message(YaAudioProcessor::Process{ ProcessResponse response = bridge.send_message(YaAudioProcessor::Process{
.instance_id = arguments.instance_id, .data = data}); .instance_id = arguments.instance_id, .data = data});
@@ -107,26 +106,25 @@ YaPluginMonolithImpl::process(Steinberg::Vst::ProcessData& data) {
return response.result; return response.result;
} }
uint32 PLUGIN_API YaPluginMonolithImpl::getTailSamples() { uint32 PLUGIN_API Vst3PluginProxyImpl::getTailSamples() {
return bridge.send_message( return bridge.send_message(
YaAudioProcessor::GetTailSamples{.instance_id = arguments.instance_id}); YaAudioProcessor::GetTailSamples{.instance_id = arguments.instance_id});
} }
tresult PLUGIN_API tresult PLUGIN_API Vst3PluginProxyImpl::setIoMode(Steinberg::Vst::IoMode mode) {
YaPluginMonolithImpl::setIoMode(Steinberg::Vst::IoMode mode) {
return bridge.send_message(YaComponent::SetIoMode{ return bridge.send_message(YaComponent::SetIoMode{
.instance_id = arguments.instance_id, .mode = mode}); .instance_id = arguments.instance_id, .mode = mode});
} }
int32 PLUGIN_API int32 PLUGIN_API
YaPluginMonolithImpl::getBusCount(Steinberg::Vst::MediaType type, Vst3PluginProxyImpl::getBusCount(Steinberg::Vst::MediaType type,
Steinberg::Vst::BusDirection dir) { Steinberg::Vst::BusDirection dir) {
return bridge.send_message(YaComponent::GetBusCount{ return bridge.send_message(YaComponent::GetBusCount{
.instance_id = arguments.instance_id, .type = type, .dir = dir}); .instance_id = arguments.instance_id, .type = type, .dir = dir});
} }
tresult PLUGIN_API tresult PLUGIN_API
YaPluginMonolithImpl::getBusInfo(Steinberg::Vst::MediaType type, Vst3PluginProxyImpl::getBusInfo(Steinberg::Vst::MediaType type,
Steinberg::Vst::BusDirection dir, Steinberg::Vst::BusDirection dir,
int32 index, int32 index,
Steinberg::Vst::BusInfo& bus /*out*/) { Steinberg::Vst::BusInfo& bus /*out*/) {
@@ -141,7 +139,7 @@ YaPluginMonolithImpl::getBusInfo(Steinberg::Vst::MediaType type,
return response.result; return response.result;
} }
tresult PLUGIN_API YaPluginMonolithImpl::getRoutingInfo( tresult PLUGIN_API Vst3PluginProxyImpl::getRoutingInfo(
Steinberg::Vst::RoutingInfo& inInfo, Steinberg::Vst::RoutingInfo& inInfo,
Steinberg::Vst::RoutingInfo& outInfo /*out*/) { Steinberg::Vst::RoutingInfo& outInfo /*out*/) {
const GetRoutingInfoResponse response = bridge.send_message( const GetRoutingInfoResponse response = bridge.send_message(
@@ -155,7 +153,7 @@ tresult PLUGIN_API YaPluginMonolithImpl::getRoutingInfo(
} }
tresult PLUGIN_API tresult PLUGIN_API
YaPluginMonolithImpl::activateBus(Steinberg::Vst::MediaType type, Vst3PluginProxyImpl::activateBus(Steinberg::Vst::MediaType type,
Steinberg::Vst::BusDirection dir, Steinberg::Vst::BusDirection dir,
int32 index, int32 index,
TBool state) { TBool state) {
@@ -167,17 +165,17 @@ YaPluginMonolithImpl::activateBus(Steinberg::Vst::MediaType type,
.state = state}); .state = state});
} }
tresult PLUGIN_API YaPluginMonolithImpl::setActive(TBool state) { tresult PLUGIN_API Vst3PluginProxyImpl::setActive(TBool state) {
return bridge.send_message(YaComponent::SetActive{ return bridge.send_message(YaComponent::SetActive{
.instance_id = arguments.instance_id, .state = state}); .instance_id = arguments.instance_id, .state = state});
} }
tresult PLUGIN_API YaPluginMonolithImpl::setState(Steinberg::IBStream* state) { tresult PLUGIN_API Vst3PluginProxyImpl::setState(Steinberg::IBStream* state) {
return bridge.send_message(YaComponent::SetState{ return bridge.send_message(YaComponent::SetState{
.instance_id = arguments.instance_id, .state = state}); .instance_id = arguments.instance_id, .state = state});
} }
tresult PLUGIN_API YaPluginMonolithImpl::getState(Steinberg::IBStream* state) { tresult PLUGIN_API Vst3PluginProxyImpl::getState(Steinberg::IBStream* state) {
const GetStateResponse response = bridge.send_message( const GetStateResponse response = bridge.send_message(
YaComponent::GetState{.instance_id = arguments.instance_id}); YaComponent::GetState{.instance_id = arguments.instance_id});
@@ -186,7 +184,7 @@ tresult PLUGIN_API YaPluginMonolithImpl::getState(Steinberg::IBStream* state) {
return response.result; return response.result;
} }
tresult PLUGIN_API YaPluginMonolithImpl::initialize(FUnknown* context) { tresult PLUGIN_API Vst3PluginProxyImpl::initialize(FUnknown* context) {
// This `context` will likely be an `IHostApplication`. If it is, we will // This `context` will likely be an `IHostApplication`. If it is, we will
// store it here, and we'll proxy through all calls to it made from the Wine // store it here, and we'll proxy through all calls to it made from the Wine
// side. Otherwise we'll still call `IPluginBase::initialize()` but with a // side. Otherwise we'll still call `IPluginBase::initialize()` but with a
@@ -210,7 +208,7 @@ tresult PLUGIN_API YaPluginMonolithImpl::initialize(FUnknown* context) {
std::move(host_application_context_args)}); std::move(host_application_context_args)});
} }
tresult PLUGIN_API YaPluginMonolithImpl::terminate() { tresult PLUGIN_API Vst3PluginProxyImpl::terminate() {
return bridge.send_message( return bridge.send_message(
YaPluginBase::Terminate{.instance_id = arguments.instance_id}); YaPluginBase::Terminate{.instance_id = arguments.instance_id});
} }
@@ -0,0 +1,95 @@
// yabridge: a Wine VST bridge
// Copyright (C) 2020 Robbert van der Helm
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
#pragma once
#include <pluginterfaces/vst/ivsthostapplication.h>
#include "../vst3.h"
class Vst3PluginProxyImpl : public Vst3PluginProxy {
public:
Vst3PluginProxyImpl(Vst3PluginBridge& bridge,
Vst3PluginProxy::ConstructArgs&& args);
/**
* When the reference count reaches zero and this destructor is called,
* we'll send a request to the Wine plugin host to destroy the corresponding
* object.
*/
~Vst3PluginProxyImpl();
/**
* We'll override the query interface to log queries for interfaces we do
* not (yet) support.
*/
tresult PLUGIN_API queryInterface(const Steinberg::TUID _iid,
void** obj) override;
// From `IAudioProcessor`
tresult PLUGIN_API
setBusArrangements(Steinberg::Vst::SpeakerArrangement* inputs,
int32 numIns,
Steinberg::Vst::SpeakerArrangement* outputs,
int32 numOuts) override;
tresult PLUGIN_API
getBusArrangement(Steinberg::Vst::BusDirection dir,
int32 index,
Steinberg::Vst::SpeakerArrangement& arr) override;
tresult PLUGIN_API canProcessSampleSize(int32 symbolicSampleSize) override;
uint32 PLUGIN_API getLatencySamples() override;
tresult PLUGIN_API
setupProcessing(Steinberg::Vst::ProcessSetup& setup) override;
tresult PLUGIN_API setProcessing(TBool state) override;
tresult PLUGIN_API process(Steinberg::Vst::ProcessData& data) override;
uint32 PLUGIN_API getTailSamples() override;
// From `IComponent`
tresult PLUGIN_API setIoMode(Steinberg::Vst::IoMode mode) override;
int32 PLUGIN_API getBusCount(Steinberg::Vst::MediaType type,
Steinberg::Vst::BusDirection dir) override;
tresult PLUGIN_API
getBusInfo(Steinberg::Vst::MediaType type,
Steinberg::Vst::BusDirection dir,
int32 index,
Steinberg::Vst::BusInfo& bus /*out*/) override;
tresult PLUGIN_API
getRoutingInfo(Steinberg::Vst::RoutingInfo& inInfo,
Steinberg::Vst::RoutingInfo& outInfo /*out*/) override;
tresult PLUGIN_API activateBus(Steinberg::Vst::MediaType type,
Steinberg::Vst::BusDirection dir,
int32 index,
TBool state) override;
tresult PLUGIN_API setActive(TBool state) override;
tresult PLUGIN_API setState(Steinberg::IBStream* state) override;
tresult PLUGIN_API getState(Steinberg::IBStream* state) override;
// From `IPluginBase`
tresult PLUGIN_API initialize(FUnknown* context) override;
tresult PLUGIN_API terminate() override;
private:
Vst3PluginBridge& bridge;
/**
* An `IHostApplication` instance if we get one through
* `IPluginBase::initialize()`. This should be the same for all plugin
* instances so we should not have to store it here separately, but for the
* sake of correctness we will.
*/
Steinberg::FUnknownPtr<Steinberg::Vst::IHostApplication>
host_application_context;
};
+3 -3
View File
@@ -108,17 +108,17 @@ Steinberg::IPluginFactory* Vst3PluginBridge::get_plugin_factory() {
YaPluginFactory::Construct{}, YaPluginFactory::Construct{},
std::pair<Vst3Logger&, bool>(logger, true)); std::pair<Vst3Logger&, bool>(logger, true));
plugin_factory = plugin_factory =
new YaPluginFactoryPluginImpl(*this, std::move(factory_args)); new YaPluginFactoryImpl(*this, std::move(factory_args));
} }
return plugin_factory; return plugin_factory;
} }
void Vst3PluginBridge::register_component(size_t instance_id, void Vst3PluginBridge::register_component(size_t instance_id,
YaPluginMonolithImpl& component) { Vst3PluginProxyImpl& component) {
std::lock_guard lock(component_instances_mutex); std::lock_guard lock(component_instances_mutex);
component_instances.emplace(instance_id, component_instances.emplace(instance_id,
std::ref<YaPluginMonolithImpl>(component)); std::ref<Vst3PluginProxyImpl>(component));
} }
void Vst3PluginBridge::unregister_component(size_t instance_id) { void Vst3PluginBridge::unregister_component(size_t instance_id) {
+3 -4
View File
@@ -24,7 +24,7 @@
#include "common.h" #include "common.h"
// Forward declaration // Forward declaration
class YaPluginMonolithImpl; class Vst3PluginProxyImpl;
/** /**
* This handles the communication between the native host and a VST3 plugin * This handles the communication between the native host and a VST3 plugin
@@ -86,8 +86,7 @@ class Vst3PluginBridge : PluginBridge<Vst3Sockets<std::jthread>> {
* *
* TODO: REname to `register_instance` or `register_object` * TODO: REname to `register_instance` or `register_object`
*/ */
void register_component(size_t instance_id, void register_component(size_t instance_id, Vst3PluginProxyImpl& component);
YaPluginMonolithImpl& component);
/** /**
* Remove a previously registered `YaComponentPluginImpl` from the list of * Remove a previously registered `YaComponentPluginImpl` from the list of
@@ -151,7 +150,7 @@ class Vst3PluginBridge : PluginBridge<Vst3Sockets<std::jthread>> {
* `register_component()` in the constractor, and an instance is then * `register_component()` in the constractor, and an instance is then
* removed through a call to `unregister_component()` in the destructor. * removed through a call to `unregister_component()` in the destructor.
*/ */
std::map<size_t, std::reference_wrapper<YaPluginMonolithImpl>> std::map<size_t, std::reference_wrapper<Vst3PluginProxyImpl>>
component_instances; component_instances;
std::mutex component_instances_mutex; std::mutex component_instances_mutex;
}; };
+7 -7
View File
@@ -60,8 +60,8 @@ void Vst3Bridge::run() {
sockets.host_vst_control.receive_messages( sockets.host_vst_control.receive_messages(
std::nullopt, std::nullopt,
overload{ overload{
[&](const YaPluginMonolith::Construct& args) [&](const Vst3PluginProxy::Construct& args)
-> YaPluginMonolith::Construct::Response { -> Vst3PluginProxy::Construct::Response {
Steinberg::TUID cid; Steinberg::TUID cid;
std::copy(args.cid.begin(), args.cid.end(), cid); std::copy(args.cid.begin(), args.cid.end(), cid);
Steinberg::IPtr<Steinberg::Vst::IComponent> component = Steinberg::IPtr<Steinberg::Vst::IComponent> component =
@@ -73,7 +73,7 @@ void Vst3Bridge::run() {
const size_t instance_id = generate_instance_id(); const size_t instance_id = generate_instance_id();
component_instances[instance_id] = std::move(component); component_instances[instance_id] = std::move(component);
return YaPluginMonolith::ConstructArgs( return Vst3PluginProxy::ConstructArgs(
component_instances[instance_id].component, component_instances[instance_id].component,
instance_id); instance_id);
} else { } else {
@@ -81,8 +81,8 @@ void Vst3Bridge::run() {
return UniversalTResult(Steinberg::kNotImplemented); return UniversalTResult(Steinberg::kNotImplemented);
} }
}, },
[&](const YaPluginMonolith::Destruct& request) [&](const Vst3PluginProxy::Destruct& request)
-> YaPluginMonolith::Destruct::Response { -> Vst3PluginProxy::Destruct::Response {
std::lock_guard lock(component_instances_mutex); std::lock_guard lock(component_instances_mutex);
component_instances.erase(request.instance_id); component_instances.erase(request.instance_id);
@@ -202,8 +202,8 @@ void Vst3Bridge::run() {
-> YaPluginBase::Initialize::Response { -> YaPluginBase::Initialize::Response {
// If we got passed a host context, we'll create a proxy object // If we got passed a host context, we'll create a proxy object
// and pass that to the initialize function. This object should // and pass that to the initialize function. This object should
// be cleaned up again during `YaPluginMonolith::Destruct`. // be cleaned up again during `Vst3PluginProxy::Destruct`.
// TOOD: This needs changing when we get to `YaHostMonolith` // TODO: This needs changing when we get to `Vst3HostProxy`
Steinberg::FUnknown* context = nullptr; Steinberg::FUnknown* context = nullptr;
if (request.host_application_context_args) { if (request.host_application_context_args) {
component_instances[request.instance_id] component_instances[request.instance_id]