From 37a74c8f986c2f3dab71b80b8ef21e8a768bac5d Mon Sep 17 00:00:00 2001 From: Robbert van der Helm Date: Wed, 13 May 2020 13:15:52 +0200 Subject: [PATCH] Get rid of the dedicated AEffect socket --- CHANGELOG.md | 6 ++++++ README.md | 11 +++-------- src/plugin/plugin-bridge.cpp | 13 ++++++++----- src/plugin/plugin-bridge.h | 13 ++++++------- src/wine-host/wine-bridge.cpp | 12 ++++++------ src/wine-host/wine-bridge.h | 13 ++++++------- 6 files changed, 35 insertions(+), 33 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 771a1348..cd9dcf79 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,12 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [Unreleased] + +### Changed + +- Changed architecture to use one less socket. + ## [1.1.4] - 2020-05-12 ### Fixed diff --git a/README.md b/README.md index c1da390d..48f6937b 100644 --- a/README.md +++ b/README.md @@ -391,11 +391,6 @@ as the _Windows VST plugin_. The whole process works as follows: `processReplacing()` and only supports The deprecated commutative `process()` function, then the Wine VST host will emulate the behavior of `processReplacing()` instead. - - The Windows VST plugin's `AEffect` object. A copy of this is sent over a - socket from the Wine VST host to the plugin after the Windows VST plugin - has finished initializing. Whenever this struct gets updated by the Windows - VST plugin, the Windows VST plugin will call the `audioMasterIOChanged()` - host callback and we'll repeat the process. The operations described above involving the host -> plugin `dispatcher()`and plugin -> host `audioMaster()` functions are all handled by first serializing @@ -429,6 +424,6 @@ as the _Windows VST plugin_. The whole process works as follows: 6. The Wine VST host loads the Windows VST plugin and starts forwarding messages over the sockets described above. 7. After the Windows VST plugin has started loading we will forward all values - from the plugin's `AEffect` struct to the Linux native VST plugin using the - socket described above. After this point the plugin will stop blocking and - has finished loading. + from the plugin's `AEffect` struct to the Linux native VST plugin over the + `dispatcher()` socket. This is only done once at startup. After this point + the plugin will stop blocking and has finished loading. diff --git a/src/plugin/plugin-bridge.cpp b/src/plugin/plugin-bridge.cpp index de236faf..ea90240b 100644 --- a/src/plugin/plugin-bridge.cpp +++ b/src/plugin/plugin-bridge.cpp @@ -68,7 +68,6 @@ PluginBridge::PluginBridge(audioMasterCallback host_callback) vst_host_callback(io_context), host_vst_parameters(io_context), host_vst_process_replacing(io_context), - vst_host_aeffect(io_context), host_callback_function(host_callback), logger(Logger::create_from_environment( create_logger_prefix(socket_endpoint.path()))), @@ -164,7 +163,6 @@ PluginBridge::PluginBridge(audioMasterCallback host_callback) socket_acceptor.accept(vst_host_callback); socket_acceptor.accept(host_vst_parameters); socket_acceptor.accept(host_vst_process_replacing); - socket_acceptor.accept(vst_host_aeffect); finished_accepting_sockets = true; // There's no need to keep the socket endpoint file around after accepting @@ -220,9 +218,14 @@ PluginBridge::PluginBridge(audioMasterCallback host_callback) }); // Read the plugin's information from the Wine process. This can only be - // done after we started accepting host callbacks as the plugin might do - // this during initialization. - const auto initialized_plugin = read_object(vst_host_aeffect); + // done after we started accepting host callbacks as the plugin will likely + // call these during its initialization. We reuse the `dispatcher()` socket + // for this since this has to be done only once. + const auto initialization_data = + read_object(host_vst_dispatch); + const auto initialized_plugin = + std::get(initialization_data.payload); + update_aeffect(plugin, initialized_plugin); } diff --git a/src/plugin/plugin-bridge.h b/src/plugin/plugin-bridge.h index b55d66d1..b180c695 100644 --- a/src/plugin/plugin-bridge.h +++ b/src/plugin/plugin-bridge.h @@ -129,6 +129,12 @@ class PluginBridge { // instance the socket named `host_vst_dispatch` forwards // `AEffect.dispatch()` calls from the native VST host to the Windows VST // plugin (through the Wine VST host). + + /** + * The socket that forwards all `dispatcher()` calls from the VST host to + * the plugin. This is also used once at startup to populate the values of + * the `AEffect` object. + */ boost::asio::local::stream_protocol::socket host_vst_dispatch; /** * Used specifically for the `effProcessEvents` opcode. This is needed @@ -145,13 +151,6 @@ class PluginBridge { boost::asio::local::stream_protocol::socket host_vst_parameters; boost::asio::local::stream_protocol::socket host_vst_process_replacing; - /** - * This socket only handles updates of the `AEffect` struct instead of - * passing through function calls. It's also used during initialization to - * pass the Wine plugin's information to the host. - */ - boost::asio::local::stream_protocol::socket vst_host_aeffect; - /** * Whether we're done accepting sockets. The plugin may hang indefinitely if * the Wine process fails to start, since then nothing will connect to our diff --git a/src/wine-host/wine-bridge.cpp b/src/wine-host/wine-bridge.cpp index 387c8bd1..800339b4 100644 --- a/src/wine-host/wine-bridge.cpp +++ b/src/wine-host/wine-bridge.cpp @@ -73,8 +73,7 @@ WineBridge::WineBridge(std::string plugin_dll_path, host_vst_dispatch_midi_events(io_context), vst_host_callback(io_context), host_vst_parameters(io_context), - host_vst_process_replacing(io_context), - vst_host_aeffect(io_context) { + host_vst_process_replacing(io_context) { // Got to love these C APIs if (plugin_handle == nullptr) { throw std::runtime_error("Could not load the Windows .dll file at '" + @@ -106,7 +105,6 @@ WineBridge::WineBridge(std::string plugin_dll_path, vst_host_callback.connect(socket_endpoint); host_vst_parameters.connect(socket_endpoint); host_vst_process_replacing.connect(socket_endpoint); - vst_host_aeffect.connect(socket_endpoint); // Initialize after communication has been set up // We'll try to do the same `get_bridge_isntance` trick as in @@ -123,9 +121,11 @@ WineBridge::WineBridge(std::string plugin_dll_path, current_bridge_instance = nullptr; plugin->ptr1 = this; - // Send the plugin's information to the Linux VST plugin. Any updates during - // runtime are handled using the `audioMasterIOChanged` host callback. - write_object(vst_host_aeffect, *plugin); + // Send the plugin's information to the Linux VST plugin. This is done over + // the `dispatch()` socket since this has to be done only once during + // initialization. Any updates during runtime are handled using the + // `audioMasterIOChanged` host callback. + write_object(host_vst_dispatch, EventResult{0, *plugin, std::nullopt}); // This works functionally identically to the `handle_dispatch()` function // below, but this socket will only handle MIDI events. This is needed diff --git a/src/wine-host/wine-bridge.h b/src/wine-host/wine-bridge.h index d03a6411..b48c2546 100644 --- a/src/wine-host/wine-bridge.h +++ b/src/wine-host/wine-bridge.h @@ -124,6 +124,12 @@ class WineBridge { // instance the socket named `host_vst_dispatch` forwards // `AEffect.dispatch()` calls from the native VST host to the Windows VST // plugin (through the Wine VST host). + + /** + * The socket that forwards all `dispatcher()` calls from the VST host to + * the plugin. This is also used once at startup to populate the values of + * the `AEffect` object. + */ boost::asio::local::stream_protocol::socket host_vst_dispatch; /** * Used specifically for the `effProcessEvents` opcode. This is needed @@ -140,13 +146,6 @@ class WineBridge { boost::asio::local::stream_protocol::socket host_vst_parameters; boost::asio::local::stream_protocol::socket host_vst_process_replacing; - /** - * This socket only handles updates of the `AEffect` struct instead of - * passing through function calls. It's also used during initialization to - * pass the Wine plugin's information to the host. - */ - boost::asio::local::stream_protocol::socket vst_host_aeffect; - /** * The thread that specifically handles `effProcessEvents` opcodes so the * plugin can still receive MIDI during GUI interaction to work around Win32