From f015739942cc03c4ae01d8331d5a62e441540ff0 Mon Sep 17 00:00:00 2001 From: Robbert van der Helm Date: Mon, 11 Jan 2021 18:50:41 +0100 Subject: [PATCH] Open and close editors without realtime priority --- CHANGELOG.md | 3 +++ src/wine-host/bridges/vst2.cpp | 19 ++++++++++++++----- src/wine-host/bridges/vst3.cpp | 11 +++++++++-- 3 files changed, 26 insertions(+), 7 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index dec1a76b..fa6aea83 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -49,6 +49,9 @@ TODO: Add an updated screenshot with some fancy VST3-only plugins to the readme scheduling priority than other tasks. With a properly configured system GUI drawing should not affect DSP load at all, but this should help with less than optimal setups some people were getting DSP load spikes with the editor open. +- Opening and closing plugin editors is now also no longer done with realtime + priority. This should get rid of any latency spikes during those operations, + as the this could otherwise preempt the threads that were processing audio. - Changed part of the build process considering [this Wine bug](https://bugs.winehq.org/show_bug.cgi?id=49138). Building with Wine 5.7 and 5.8 required a change, but that change now breaks builds using Wine 6.0 diff --git a/src/wine-host/bridges/vst2.cpp b/src/wine-host/bridges/vst2.cpp index 410b6ba3..1addbe33 100644 --- a/src/wine-host/bridges/vst2.cpp +++ b/src/wine-host/bridges/vst2.cpp @@ -386,21 +386,30 @@ intptr_t Vst2Bridge::dispatch_wrapper(AEffect* plugin, // provided by the host, and let the plugin embed itself into // the Wine window const auto x11_handle = reinterpret_cast(data); + + // NOTE: Just like in the event loop, we want to run this with lower + // priority to prevent whatever operation the plugin does + // while it's loading its editor from preempting the audio + // thread. + set_realtime_priority(false); Editor& editor_instance = editor.emplace(config, x11_handle, [plugin = this->plugin]() { plugin->dispatcher(plugin, effEditIdle, 0, 0, nullptr, 0.0); }); + const intptr_t result = + plugin->dispatcher(plugin, opcode, index, value, + editor_instance.get_win32_handle(), option); + set_realtime_priority(true); - return plugin->dispatcher(plugin, opcode, index, value, - editor_instance.get_win32_handle(), - option); + return result; } break; case effEditClose: { + // Cleanup is handled through RAII + set_realtime_priority(false); const intptr_t return_value = plugin->dispatcher(plugin, opcode, index, value, data, option); - - // Cleanup is handled through RAII editor.reset(); + set_realtime_priority(true); return return_value; } break; diff --git a/src/wine-host/bridges/vst3.cpp b/src/wine-host/bridges/vst3.cpp index 452b728a..6a5bf3e1 100644 --- a/src/wine-host/bridges/vst3.cpp +++ b/src/wine-host/bridges/vst3.cpp @@ -552,15 +552,20 @@ void Vst3Bridge::run() { // be done in the main UI thread return main_context .run_in_context([&]() { + // NOTE: Just like in the event loop, we want to run + // this with lower priority to prevent whatever + // operation the plugin does while it's loading + // its editor from preempting the audio thread. + set_realtime_priority(false); Editor& editor_instance = object_instances[request.owner_instance_id] .editor.emplace(config, x11_handle); - const tresult result = object_instances[request.owner_instance_id] .plug_view_instance->plug_view->attached( editor_instance.get_win32_handle(), type.c_str()); + set_realtime_priority(true); // Get rid of the editor again if the plugin didn't // embed itself in it @@ -577,12 +582,14 @@ void Vst3Bridge::run() { -> YaPlugView::Removed::Response { return main_context .run_in_context([&]() { + // Cleanup is handled through RAII + set_realtime_priority(false); const tresult result = object_instances[request.owner_instance_id] .plug_view_instance->plug_view->removed(); - object_instances[request.owner_instance_id] .editor.reset(); + set_realtime_priority(true); return result; })