mirror of
https://github.com/robbert-vdh/yabridge.git
synced 2026-05-10 04:30:12 +02:00
Move wine-bridge.h -> bridges/vst2.h
This way we can structure the group handling and a potential future VST3 bridge in the same way.
This commit is contained in:
@@ -419,7 +419,7 @@ as the _Windows VST plugin_. The whole process works as follows:
|
|||||||
in the `DispatchDataConverter` and `HostCallbackDataCovnerter` classes for
|
in the `DispatchDataConverter` and `HostCallbackDataCovnerter` classes for
|
||||||
the `dispatcher()` and `audioMaster()` functions respectively. For operations
|
the `dispatcher()` and `audioMaster()` functions respectively. For operations
|
||||||
involving the plugin editor there is also some extra glue in
|
involving the plugin editor there is also some extra glue in
|
||||||
`WineBridge::dispatch_wrapper`. On the receiving end of the function calls,
|
`Vst2Bridge::dispatch_wrapper`. On the receiving end of the function calls,
|
||||||
the `passthrough_event()` function which calls the callback functions and
|
the `passthrough_event()` function which calls the callback functions and
|
||||||
handles the marshalling between our data types created by the
|
handles the marshalling between our data types created by the
|
||||||
`*DataConverter` classes and the VST API's different pointer types. This
|
`*DataConverter` classes and the VST API's different pointer types. This
|
||||||
|
|||||||
+1
-1
@@ -86,10 +86,10 @@ shared_library(
|
|||||||
host_sources = [
|
host_sources = [
|
||||||
'src/common/logging.cpp',
|
'src/common/logging.cpp',
|
||||||
'src/common/serialization.cpp',
|
'src/common/serialization.cpp',
|
||||||
|
'src/wine-host/bridges/vst2.cpp',
|
||||||
'src/wine-host/editor.cpp',
|
'src/wine-host/editor.cpp',
|
||||||
'src/wine-host/editor.cpp',
|
'src/wine-host/editor.cpp',
|
||||||
'src/wine-host/utils.cpp',
|
'src/wine-host/utils.cpp',
|
||||||
'src/wine-host/wine-bridge.cpp',
|
|
||||||
version_header,
|
version_header,
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|||||||
@@ -165,7 +165,7 @@ PluginBridge::PluginBridge(audioMasterCallback host_callback)
|
|||||||
try {
|
try {
|
||||||
while (true) {
|
while (true) {
|
||||||
// TODO: Think of a nicer way to structure this and the similar
|
// TODO: Think of a nicer way to structure this and the similar
|
||||||
// handler in `WineBridge::handle_dispatch_midi_events`
|
// handler in `Vst2Bridge::handle_dispatch_midi_events`
|
||||||
receive_event(
|
receive_event(
|
||||||
vst_host_callback, std::pair<Logger&, bool>(logger, false),
|
vst_host_callback, std::pair<Logger&, bool>(logger, false),
|
||||||
[&](Event& event) {
|
[&](Event& event) {
|
||||||
|
|||||||
@@ -65,7 +65,7 @@ class PluginBridge {
|
|||||||
* Ask the VST plugin to process audio for us. If the plugin somehow does
|
* Ask the VST plugin to process audio for us. If the plugin somehow does
|
||||||
* not support `processReplacing()` and only supports the old `process()`
|
* not support `processReplacing()` and only supports the old `process()`
|
||||||
* function, then this will be handled implicitely in
|
* function, then this will be handled implicitely in
|
||||||
* `WineBridge::handle_process_replacing()`.
|
* `Vst2Bridge::handle_process_replacing()`.
|
||||||
*/
|
*/
|
||||||
void process_replacing(AEffect* plugin,
|
void process_replacing(AEffect* plugin,
|
||||||
float** inputs,
|
float** inputs,
|
||||||
|
|||||||
@@ -14,12 +14,12 @@
|
|||||||
// 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 "wine-bridge.h"
|
#include "vst2.h"
|
||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
#include "../common/communication.h"
|
#include "../../common/communication.h"
|
||||||
#include "../common/events.h"
|
#include "../../common/events.h"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A function pointer to what should be the entry point of a VST plugin.
|
* A function pointer to what should be the entry point of a VST plugin.
|
||||||
@@ -30,7 +30,7 @@ using VstEntryPoint = AEffect*(VST_CALL_CONV*)(audioMasterCallback);
|
|||||||
* This ugly global is needed so we can get the instance of a `Brdige` class
|
* This ugly global is needed so we can get the instance of a `Brdige` class
|
||||||
* from an `AEffect` when it performs a host callback during its initialization.
|
* from an `AEffect` when it performs a host callback during its initialization.
|
||||||
*/
|
*/
|
||||||
WineBridge* current_bridge_instance = nullptr;
|
Vst2Bridge* current_bridge_instance = nullptr;
|
||||||
|
|
||||||
intptr_t VST_CALL_CONV
|
intptr_t VST_CALL_CONV
|
||||||
host_callback_proxy(AEffect*, int, int, intptr_t, void*, float);
|
host_callback_proxy(AEffect*, int, int, intptr_t, void*, float);
|
||||||
@@ -43,12 +43,12 @@ uint32_t WINAPI handle_parameters_proxy(void*);
|
|||||||
uint32_t WINAPI handle_process_replacing_proxy(void*);
|
uint32_t WINAPI handle_process_replacing_proxy(void*);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Fetch the WineBridge instance stored in one of the two pointers reserved
|
* Fetch the Vst2Bridge instance stored in one of the two pointers reserved
|
||||||
* for the host of the hosted VST plugin. This is sadly needed as a workaround
|
* for the host of the hosted VST plugin. This is sadly needed as a workaround
|
||||||
* to avoid using globals since we need free function pointers to interface with
|
* to avoid using globals since we need free function pointers to interface with
|
||||||
* the VST C API.
|
* the VST C API.
|
||||||
*/
|
*/
|
||||||
WineBridge& get_bridge_instance(const AEffect* plugin) {
|
Vst2Bridge& get_bridge_instance(const AEffect* plugin) {
|
||||||
// This is needed during the initialization of the plugin since we can only
|
// This is needed during the initialization of the plugin since we can only
|
||||||
// add our own pointer after it's done initializing
|
// add our own pointer after it's done initializing
|
||||||
if (current_bridge_instance != nullptr) {
|
if (current_bridge_instance != nullptr) {
|
||||||
@@ -57,10 +57,10 @@ WineBridge& get_bridge_instance(const AEffect* plugin) {
|
|||||||
return *current_bridge_instance;
|
return *current_bridge_instance;
|
||||||
}
|
}
|
||||||
|
|
||||||
return *static_cast<WineBridge*>(plugin->ptr1);
|
return *static_cast<Vst2Bridge*>(plugin->ptr1);
|
||||||
}
|
}
|
||||||
|
|
||||||
WineBridge::WineBridge(std::string plugin_dll_path,
|
Vst2Bridge::Vst2Bridge(std::string plugin_dll_path,
|
||||||
std::string socket_endpoint_path)
|
std::string socket_endpoint_path)
|
||||||
: plugin_handle(LoadLibrary(plugin_dll_path.c_str()), FreeLibrary),
|
: plugin_handle(LoadLibrary(plugin_dll_path.c_str()), FreeLibrary),
|
||||||
io_context(),
|
io_context(),
|
||||||
@@ -135,7 +135,7 @@ WineBridge::WineBridge(std::string plugin_dll_path,
|
|||||||
Win32Thread(handle_process_replacing_proxy, this);
|
Win32Thread(handle_process_replacing_proxy, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
void WineBridge::handle_dispatch() {
|
void Vst2Bridge::handle_dispatch() {
|
||||||
using namespace std::placeholders;
|
using namespace std::placeholders;
|
||||||
|
|
||||||
// For our communication we use simple threads and blocking operations
|
// For our communication we use simple threads and blocking operations
|
||||||
@@ -145,7 +145,7 @@ void WineBridge::handle_dispatch() {
|
|||||||
while (true) {
|
while (true) {
|
||||||
receive_event(host_vst_dispatch, std::nullopt,
|
receive_event(host_vst_dispatch, std::nullopt,
|
||||||
passthrough_event(
|
passthrough_event(
|
||||||
plugin, std::bind(&WineBridge::dispatch_wrapper,
|
plugin, std::bind(&Vst2Bridge::dispatch_wrapper,
|
||||||
this, _1, _2, _3, _4, _5, _6)));
|
this, _1, _2, _3, _4, _5, _6)));
|
||||||
|
|
||||||
// Because of the way the Win32 API works we have to process events
|
// Because of the way the Win32 API works we have to process events
|
||||||
@@ -156,7 +156,7 @@ void WineBridge::handle_dispatch() {
|
|||||||
// run this loop. The only exception is a in specific situation that
|
// run this loop. The only exception is a in specific situation that
|
||||||
// can cause a race condition in some plugins because of incorrect
|
// can cause a race condition in some plugins because of incorrect
|
||||||
// assumptions made by the plugin. See the dostring for
|
// assumptions made by the plugin. See the dostring for
|
||||||
// `WineBridge::editor` for more information.
|
// `Vst2Bridge::editor` for more information.
|
||||||
std::visit(overload{[](Editor& editor) { editor.handle_events(); },
|
std::visit(overload{[](Editor& editor) { editor.handle_events(); },
|
||||||
[](std::monostate&) {
|
[](std::monostate&) {
|
||||||
MSG msg;
|
MSG msg;
|
||||||
@@ -170,7 +170,7 @@ void WineBridge::handle_dispatch() {
|
|||||||
[](EditorOpening&) {
|
[](EditorOpening&) {
|
||||||
// Don't handle any events in this
|
// Don't handle any events in this
|
||||||
// particular case as explained in
|
// particular case as explained in
|
||||||
// `WineBridge::editor`
|
// `Vst2Bridge::editor`
|
||||||
}},
|
}},
|
||||||
editor);
|
editor);
|
||||||
}
|
}
|
||||||
@@ -180,7 +180,7 @@ void WineBridge::handle_dispatch() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
[[noreturn]] void WineBridge::handle_dispatch_midi_events() {
|
[[noreturn]] void Vst2Bridge::handle_dispatch_midi_events() {
|
||||||
while (true) {
|
while (true) {
|
||||||
receive_event(
|
receive_event(
|
||||||
host_vst_dispatch_midi_events, std::nullopt, [&](Event& event) {
|
host_vst_dispatch_midi_events, std::nullopt, [&](Event& event) {
|
||||||
@@ -221,14 +221,14 @@ void WineBridge::handle_dispatch() {
|
|||||||
// Maybe this should just be a hard error instead, since it
|
// Maybe this should just be a hard error instead, since it
|
||||||
// should never happen
|
// should never happen
|
||||||
return passthrough_event(
|
return passthrough_event(
|
||||||
plugin, std::bind(&WineBridge::dispatch_wrapper, this,
|
plugin, std::bind(&Vst2Bridge::dispatch_wrapper, this,
|
||||||
_1, _2, _3, _4, _5, _6))(event);
|
_1, _2, _3, _4, _5, _6))(event);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
[[noreturn]] void WineBridge::handle_parameters() {
|
[[noreturn]] void Vst2Bridge::handle_parameters() {
|
||||||
while (true) {
|
while (true) {
|
||||||
// Both `getParameter` and `setParameter` functions are passed
|
// Both `getParameter` and `setParameter` functions are passed
|
||||||
// through on this socket since they have a lot of overlap. The
|
// through on this socket since they have a lot of overlap. The
|
||||||
@@ -251,7 +251,7 @@ void WineBridge::handle_dispatch() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
[[noreturn]] void WineBridge::handle_process_replacing() {
|
[[noreturn]] void Vst2Bridge::handle_process_replacing() {
|
||||||
std::vector<std::vector<float>> output_buffers(plugin->numOutputs);
|
std::vector<std::vector<float>> output_buffers(plugin->numOutputs);
|
||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
@@ -307,7 +307,7 @@ void WineBridge::handle_dispatch() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
intptr_t WineBridge::dispatch_wrapper(AEffect* plugin,
|
intptr_t Vst2Bridge::dispatch_wrapper(AEffect* plugin,
|
||||||
int opcode,
|
int opcode,
|
||||||
int index,
|
int index,
|
||||||
intptr_t value,
|
intptr_t value,
|
||||||
@@ -448,7 +448,7 @@ class HostCallbackDataConverter : DefaultDataConverter {
|
|||||||
std::optional<VstTimeInfo>& time_info;
|
std::optional<VstTimeInfo>& time_info;
|
||||||
};
|
};
|
||||||
|
|
||||||
intptr_t WineBridge::host_callback(AEffect* effect,
|
intptr_t Vst2Bridge::host_callback(AEffect* effect,
|
||||||
int opcode,
|
int opcode,
|
||||||
int index,
|
int index,
|
||||||
intptr_t value,
|
intptr_t value,
|
||||||
@@ -470,13 +470,13 @@ intptr_t VST_CALL_CONV host_callback_proxy(AEffect* effect,
|
|||||||
}
|
}
|
||||||
|
|
||||||
uint32_t WINAPI handle_dispatch_midi_events_proxy(void* instance) {
|
uint32_t WINAPI handle_dispatch_midi_events_proxy(void* instance) {
|
||||||
static_cast<WineBridge*>(instance)->handle_dispatch_midi_events();
|
static_cast<Vst2Bridge*>(instance)->handle_dispatch_midi_events();
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t WINAPI handle_parameters_proxy(void* instance) {
|
uint32_t WINAPI handle_parameters_proxy(void* instance) {
|
||||||
static_cast<WineBridge*>(instance)->handle_parameters();
|
static_cast<Vst2Bridge*>(instance)->handle_parameters();
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t WINAPI handle_process_replacing_proxy(void* instance) {
|
uint32_t WINAPI handle_process_replacing_proxy(void* instance) {
|
||||||
static_cast<WineBridge*>(instance)->handle_process_replacing();
|
static_cast<Vst2Bridge*>(instance)->handle_process_replacing();
|
||||||
}
|
}
|
||||||
@@ -16,7 +16,7 @@
|
|||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "boost-fix.h"
|
#include "../boost-fix.h"
|
||||||
|
|
||||||
#define NOMINMAX
|
#define NOMINMAX
|
||||||
#define NOSERVICE
|
#define NOSERVICE
|
||||||
@@ -29,23 +29,23 @@
|
|||||||
#include <boost/asio/local/stream_protocol.hpp>
|
#include <boost/asio/local/stream_protocol.hpp>
|
||||||
#include <mutex>
|
#include <mutex>
|
||||||
|
|
||||||
#include "../common/logging.h"
|
#include "../../common/logging.h"
|
||||||
#include "editor.h"
|
#include "../editor.h"
|
||||||
#include "utils.h"
|
#include "../utils.h"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A marker struct to indicate that the editor is about to be opened.
|
* A marker struct to indicate that the editor is about to be opened.
|
||||||
*
|
*
|
||||||
* @see WineBridge::editor
|
* @see Vst2Bridge::editor
|
||||||
*/
|
*/
|
||||||
struct EditorOpening {};
|
struct EditorOpening {};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This handles the communication between the Linux native VST plugin and the
|
* This handles the communication between the Linux native VST plugin and the
|
||||||
* Wine VST host. The functions below should be used as callback functions in an
|
* Wine VST host when hosting VST2 plugins. The functions below should be used
|
||||||
* `AEffect` object.
|
* as callback functions in an `AEffect` object.
|
||||||
*/
|
*/
|
||||||
class WineBridge {
|
class Vst2Bridge {
|
||||||
public:
|
public:
|
||||||
/**
|
/**
|
||||||
* Initializes the Windows VST plugin and set up communication with the
|
* Initializes the Windows VST plugin and set up communication with the
|
||||||
@@ -59,7 +59,7 @@ class WineBridge {
|
|||||||
* @throw std::runtime_error Thrown when the VST plugin could not be loaded,
|
* @throw std::runtime_error Thrown when the VST plugin could not be loaded,
|
||||||
* or if communication could not be set up.
|
* or if communication could not be set up.
|
||||||
*/
|
*/
|
||||||
WineBridge(std::string plugin_dll_path, std::string socket_endpoint_path);
|
Vst2Bridge(std::string plugin_dll_path, std::string socket_endpoint_path);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Handle events on the main thread until the plugin quits. This can't be
|
* Handle events on the main thread until the plugin quits. This can't be
|
||||||
@@ -29,7 +29,7 @@
|
|||||||
#include <src/common/config/config.h>
|
#include <src/common/config/config.h>
|
||||||
#include <src/common/config/version.h>
|
#include <src/common/config/version.h>
|
||||||
|
|
||||||
#include "wine-bridge.h"
|
#include "bridges/vst2.h"
|
||||||
|
|
||||||
// FIXME: `std::filesystem` is broken in wineg++, at least under Wine 5.8. Any
|
// FIXME: `std::filesystem` is broken in wineg++, at least under Wine 5.8. Any
|
||||||
// path operation will thrown an encoding related error.
|
// path operation will thrown an encoding related error.
|
||||||
|
|||||||
@@ -20,7 +20,7 @@
|
|||||||
#include <src/common/config/config.h>
|
#include <src/common/config/config.h>
|
||||||
#include <src/common/config/version.h>
|
#include <src/common/config/version.h>
|
||||||
|
|
||||||
#include "wine-bridge.h"
|
#include "bridges/vst2.h"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This is the default VST host application. It will load the specified VST2
|
* This is the default VST host application. It will load the specified VST2
|
||||||
@@ -55,7 +55,7 @@ int __cdecl main(int argc, char* argv[]) {
|
|||||||
#endif
|
#endif
|
||||||
<< std::endl;
|
<< std::endl;
|
||||||
try {
|
try {
|
||||||
WineBridge bridge(plugin_dll_path, socket_endpoint_path);
|
Vst2Bridge bridge(plugin_dll_path, socket_endpoint_path);
|
||||||
std::cerr << "Finished initializing '" << plugin_dll_path << "'"
|
std::cerr << "Finished initializing '" << plugin_dll_path << "'"
|
||||||
<< std::endl;
|
<< std::endl;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user