From db1a51af5c6b33e06579af0a1216299d40fce74a Mon Sep 17 00:00:00 2001 From: Robbert van der Helm Date: Fri, 4 Dec 2020 14:59:46 +0100 Subject: [PATCH] Add serialization primitives for VST3 --- src/common/serialization/vst2.h | 4 +- src/common/serialization/vst3.h | 100 ++++++++++++++++++++++++++++++++ 2 files changed, 102 insertions(+), 2 deletions(-) create mode 100644 src/common/serialization/vst3.h diff --git a/src/common/serialization/vst2.h b/src/common/serialization/vst2.h index ada95336..16766edd 100644 --- a/src/common/serialization/vst2.h +++ b/src/common/serialization/vst2.h @@ -16,14 +16,14 @@ #pragma once +#include + #include #include #include #include #include -#include - #include "../vst24.h" #include "common.h" diff --git a/src/common/serialization/vst3.h b/src/common/serialization/vst3.h new file mode 100644 index 00000000..3267de2b --- /dev/null +++ b/src/common/serialization/vst3.h @@ -0,0 +1,100 @@ +// 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 . + +#pragma once + +#include + +#include + +#include "../configuration.h" +#include "common.h" + +// Event handling for our VST3 plugins works slightly different from how we +// handle VST2 plugins. VST3 does not have a centralized event dispatching +// interface like VST2 does, and it uses a bunch of separate interfaces instead. +// Instead of having an a single event/result with accompanying payload values +// for both host -> plugin `dispatcher()` and plugin -> host `audioMaster()` +// calls, we'll just send request and response payloads directly without any +// metadata. We also split everything up into host -> plugin 'control' payloads +// and plugin -> host 'callback' payloads for maintainability's sake. + +// TODO: If this approach works, maybe we can also refactor the VST2 handling to +// do this since it's a bit safer and easier to read + +/** + * Marker struct to indicate the other side (the plugin) should send a copy of + * the configuration. + */ +struct WantsConfiguration { + using Response = Configuration; +}; + +/** + * When we send a control message from the plugin to the Wine VST host, this + * encodes the information we request or the operation we want to perform. A + * request of type `T` should send back a `CallbackResponse` containing + * `T::Reponse`. + * + * @relates ControlResponse + */ +using ControlRequest = std::variant<>; + +template +void serialize(S& s, ControlRequest& payload) { + s.ext(payload, bitsery::ext::StdVariant{}); +} + +/** + * A response to a control message. Tee `T::Reponse` for the correct type to + * return here. + * + * @relates ControlRrequest + */ +using ControlResponse = std::variant<>; + +template +void serialize(S& s, ControlResponse& payload) { + s.ext(payload, bitsery::ext::StdVariant{}); +} + +/** + * When we do a callback from the Wine VST host to the plugin, this encodes the + * information we want or the operation we want to perform. A request of type + * `T` should send back a `CallbackResponse` containing `T::Reponse`. + * + * @relates CallbackResponse + */ +using CallbackRequest = std::variant; + +template +void serialize(S& s, CallbackRequest& payload) { + s.ext(payload, bitsery::ext::StdVariant{[](S&, WantsConfiguration&) {}}); +} + +/** + * A response to a callback. Tee `T::Reponse` for the correct type to return + * here. + * + * @relates CallbackRrequest + */ +using CallbackResponse = std::variant; + +template +void serialize(S& s, CallbackResponse& payload) { + s.ext(payload, bitsery::ext::StdVariant{ + [](S& s, Configuration& config) { s.object(config); }}); +}