mirror of
https://github.com/robbert-vdh/yabridge.git
synced 2026-05-10 04:30:12 +02:00
Add the Vst3Bridge boilerplate
This commit is contained in:
@@ -0,0 +1,65 @@
|
|||||||
|
// 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 <atomic>
|
||||||
|
|
||||||
|
#include "common.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Manages all the sockets used for communicating between the plugin and the
|
||||||
|
* Wine host when hosting a VST3 plugin.
|
||||||
|
*
|
||||||
|
* On the plugin side this class should be initialized with `listen` set to
|
||||||
|
* `true` before launching the Wine VST host. This will start listening on the
|
||||||
|
* sockets, and the call to `connect()` will then accept any incoming
|
||||||
|
* connections.
|
||||||
|
*
|
||||||
|
* @tparam Thread The thread implementation to use. On the Linux side this
|
||||||
|
* should be `std::jthread` and on the Wine side this should be `Win32Thread`.
|
||||||
|
*/
|
||||||
|
template <typename Thread>
|
||||||
|
class Vst3Sockets : public Sockets {
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* Sets up the sockets using the specified base directory. The sockets won't
|
||||||
|
* be active until `connect()` gets called.
|
||||||
|
*
|
||||||
|
* @param io_context The IO context the sockets should be bound to. Relevant
|
||||||
|
* when doing asynchronous operations.
|
||||||
|
* @param endpoint_base_dir The base directory that will be used for the
|
||||||
|
* Unix domain sockets.
|
||||||
|
* @param listen If `true`, start listening on the sockets. Incoming
|
||||||
|
* connections will be accepted when `connect()` gets called. This should
|
||||||
|
* be set to `true` on the plugin side, and `false` on the Wine host side.
|
||||||
|
*
|
||||||
|
* @see Vst3Sockets::connect
|
||||||
|
*/
|
||||||
|
Vst3Sockets(boost::asio::io_context& io_context,
|
||||||
|
const boost::filesystem::path& endpoint_base_dir,
|
||||||
|
bool listen)
|
||||||
|
: Sockets(endpoint_base_dir) {}
|
||||||
|
|
||||||
|
~Vst3Sockets() { close(); }
|
||||||
|
|
||||||
|
void connect() override {}
|
||||||
|
|
||||||
|
void close() override {
|
||||||
|
// Manually close all sockets so we break out of any blocking operations
|
||||||
|
// that may still be active
|
||||||
|
}
|
||||||
|
};
|
||||||
@@ -208,7 +208,9 @@ void GroupBridge::accept_requests() {
|
|||||||
break;
|
break;
|
||||||
case PluginType::vst3:
|
case PluginType::vst3:
|
||||||
#ifdef WITH_VST3
|
#ifdef WITH_VST3
|
||||||
throw std::runtime_error("TODO: Not yet implemented");
|
bridge = std::make_unique<Vst3Bridge>(
|
||||||
|
main_context, request.plugin_path,
|
||||||
|
request.endpoint_base_dir);
|
||||||
#else
|
#else
|
||||||
throw std::runtime_error(
|
throw std::runtime_error(
|
||||||
"This version of yabridge has not been compiled "
|
"This version of yabridge has not been compiled "
|
||||||
|
|||||||
@@ -28,7 +28,6 @@
|
|||||||
#include <vestige/aeffectx.h>
|
#include <vestige/aeffectx.h>
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
|
|
||||||
#include <boost/asio/local/stream_protocol.hpp>
|
|
||||||
#include <mutex>
|
#include <mutex>
|
||||||
|
|
||||||
#include "../../common/communication/vst2.h"
|
#include "../../common/communication/vst2.h"
|
||||||
@@ -43,14 +42,14 @@
|
|||||||
class Vst2Bridge : public HostBridge {
|
class Vst2Bridge : public HostBridge {
|
||||||
public:
|
public:
|
||||||
/**
|
/**
|
||||||
* Initializes the Windows VST plugin and set up communication with the
|
* Initializes the Windows VST2 plugin and set up communication with the
|
||||||
* native Linux VST plugin.
|
* native Linux VST2 plugin.
|
||||||
*
|
*
|
||||||
* @param main_context The main IO context for this application. Most events
|
* @param main_context The main IO context for this application. Most events
|
||||||
* will be dispatched to this context, and the event handling loop should
|
* will be dispatched to this context, and the event handling loop should
|
||||||
* also be run from this context.
|
* also be run from this context.
|
||||||
* @param plugin_dll_path A (Unix style) path to the VST plugin .dll file to
|
* @param plugin_dll_path A (Unix style) path to the VST2 plugin .dll file
|
||||||
* load.
|
* to load.
|
||||||
* @param endpoint_base_dir The base directory used for the socket
|
* @param endpoint_base_dir The base directory used for the socket
|
||||||
* endpoints. See `Sockets` for more information.
|
* endpoints. See `Sockets` for more information.
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -18,24 +18,38 @@
|
|||||||
|
|
||||||
#include "../boost-fix.h"
|
#include "../boost-fix.h"
|
||||||
|
|
||||||
// TODO: Do something with this, I just wanted to get the build working
|
|
||||||
#include <public.sdk/source/vst/hosting/module_win32.cpp>
|
#include <public.sdk/source/vst/hosting/module_win32.cpp>
|
||||||
|
|
||||||
void justdewit(const std::string& path) {
|
Vst3Bridge::Vst3Bridge(MainContext& main_context,
|
||||||
|
std::string plugin_dll_path,
|
||||||
|
std::string endpoint_base_dir)
|
||||||
|
: HostBridge(plugin_dll_path),
|
||||||
|
main_context(main_context),
|
||||||
|
sockets(main_context.context, endpoint_base_dir, false) {
|
||||||
std::string error;
|
std::string error;
|
||||||
std::shared_ptr<VST3::Hosting::Module> plugin =
|
module = VST3::Hosting::Win32Module::create(plugin_dll_path, error);
|
||||||
VST3::Hosting::Win32Module::create(path, error);
|
|
||||||
|
|
||||||
if (plugin) {
|
// TODO: Do something more useful with this
|
||||||
|
if (module) {
|
||||||
// TODO: They use some thin wrappers around the interfaces, we can
|
// TODO: They use some thin wrappers around the interfaces, we can
|
||||||
// probably reuse these instead of having to make our own
|
// probably reuse these instead of having to make our own
|
||||||
VST3::Hosting::FactoryInfo info = plugin->getFactory().info();
|
VST3::Hosting::FactoryInfo info = module->getFactory().info();
|
||||||
std::cout << "Plugin name: " << plugin->getName() << std::endl;
|
std::cout << "Plugin name: " << module->getName() << std::endl;
|
||||||
std::cout << "Vendor: " << info.vendor() << std::endl;
|
std::cout << "Vendor: " << info.vendor() << std::endl;
|
||||||
std::cout << "URL: " << info.url() << std::endl;
|
std::cout << "URL: " << info.url() << std::endl;
|
||||||
std::cout << "Send spam to: " << info.email() << std::endl;
|
std::cout << "Send spam to: " << info.email() << std::endl;
|
||||||
} else {
|
} else {
|
||||||
std::cerr << "Ohnoes!" << std::endl;
|
throw std::runtime_error("Could not load the VST3 module for '" +
|
||||||
std::cerr << error << std::endl;
|
plugin_dll_path + "': " + error);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sockets.connect();
|
||||||
|
|
||||||
|
// TODO: We should send a copy of the configuration from the plugin at this
|
||||||
|
// point config = sockets.host_vst_control.receive_single<Configuration>();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Vst3Bridge::run() {
|
||||||
|
// TODO: Do something
|
||||||
|
std::cerr << "TODO: Not yet implemented" << std::endl;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,4 +18,65 @@
|
|||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
void justdewit(const std::string& path);
|
#include <public.sdk/source/vst/hosting/module.h>
|
||||||
|
|
||||||
|
#include "../../common/communication/vst3.h"
|
||||||
|
#include "../../common/configuration.h"
|
||||||
|
#include "common.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This hosts a Windows VST3 plugin, forwards messages sent by the Linux VST
|
||||||
|
* plugin and provides host callback function for the plugin to talk back.
|
||||||
|
*/
|
||||||
|
class Vst3Bridge : public HostBridge {
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* Initializes the Windows VST3 plugin and set up communication with the
|
||||||
|
* native Linux VST plugin.
|
||||||
|
*
|
||||||
|
* @param main_context The main IO context for this application. Most events
|
||||||
|
* will be dispatched to this context, and the event handling loop should
|
||||||
|
* also be run from this context.
|
||||||
|
* @param plugin_dll_path A (Unix style) path to the VST plugin .dll file to
|
||||||
|
* load.
|
||||||
|
* @param endpoint_base_dir The base directory used for the socket
|
||||||
|
* endpoints. See `Sockets` for more information.
|
||||||
|
*
|
||||||
|
* @note The object has to be constructed from the same thread that calls
|
||||||
|
* `main_context.run()`.
|
||||||
|
*
|
||||||
|
* @throw std::runtime_error Thrown when the VST plugin could not be loaded,
|
||||||
|
* or if communication could not be set up.
|
||||||
|
*/
|
||||||
|
Vst3Bridge(MainContext& main_context,
|
||||||
|
std::string plugin_dll_path,
|
||||||
|
std::string endpoint_base_dir);
|
||||||
|
|
||||||
|
void run() override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
/**
|
||||||
|
* The IO context used for event handling so that all events and window
|
||||||
|
* message handling can be performed from a single thread, even when hosting
|
||||||
|
* multiple plugins.
|
||||||
|
*/
|
||||||
|
MainContext& main_context;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The configuration for this instance of yabridge based on the `.so` file
|
||||||
|
* that got loaded by the host. This configuration gets loaded on the plugin
|
||||||
|
* side, and then sent over to the Wine host as part of the startup process.
|
||||||
|
*/
|
||||||
|
Configuration config;
|
||||||
|
|
||||||
|
std::shared_ptr<VST3::Hosting::Module> module;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* All sockets used for communicating with this specific plugin.
|
||||||
|
*
|
||||||
|
* NOTE: This is defined **after** the threads on purpose. This way the
|
||||||
|
* sockets will be closed first, and we can then safely wait for the
|
||||||
|
* threads to exit.
|
||||||
|
*/
|
||||||
|
Vst3Sockets<Win32Thread> sockets;
|
||||||
|
};
|
||||||
|
|||||||
@@ -85,10 +85,8 @@ main(int argc, char* argv[]) {
|
|||||||
break;
|
break;
|
||||||
case PluginType::vst3:
|
case PluginType::vst3:
|
||||||
#ifdef WITH_VST3
|
#ifdef WITH_VST3
|
||||||
justdewit(plugin_location);
|
bridge = std::make_unique<Vst3Bridge>(
|
||||||
|
main_context, plugin_location, socket_endpoint_path);
|
||||||
std::cerr << "TODO: Not yet implemented" << std::endl;
|
|
||||||
return 1;
|
|
||||||
#else
|
#else
|
||||||
std::cerr << "This version of yabridge has not been compiled "
|
std::cerr << "This version of yabridge has not been compiled "
|
||||||
"with VST3 support"
|
"with VST3 support"
|
||||||
|
|||||||
Reference in New Issue
Block a user