mirror of
https://github.com/robbert-vdh/yabridge.git
synced 2026-05-10 04:30:12 +02:00
Make realtime priority setting more granular
On the plugin side.
This commit is contained in:
+12
-3
@@ -57,13 +57,13 @@ TODO: Add an updated screenshot with some fancy VST3-only plugins to the readme
|
|||||||
- `libyabridge.so` is now called `libyabridge-vst2.so`. If you're using
|
- `libyabridge.so` is now called `libyabridge-vst2.so`. If you're using
|
||||||
yabridgectl then nothing changes here. **To avoid any confusion in the future,
|
yabridgectl then nothing changes here. **To avoid any confusion in the future,
|
||||||
please remove the old `libyabridge.so` file before upgrading.**
|
please remove the old `libyabridge.so` file before upgrading.**
|
||||||
- Slightly increased responsiveness when resizing plugin GUIs by preventing
|
|
||||||
unnecessary blitting. This also reduces flickering with plugins that don't do
|
|
||||||
double buffering.
|
|
||||||
- Window closing is now deferred. This means that when closing the editor
|
- Window closing is now deferred. This means that when closing the editor
|
||||||
window, the host no longer has to wait for Wine to fully close the window.
|
window, the host no longer has to wait for Wine to fully close the window.
|
||||||
Most hosts already do something similar themselves, so this may not make any
|
Most hosts already do something similar themselves, so this may not make any
|
||||||
difference in responsiveness.
|
difference in responsiveness.
|
||||||
|
- Slightly increased responsiveness when resizing plugin GUIs by preventing
|
||||||
|
unnecessary blitting. This also reduces flickering with plugins that don't do
|
||||||
|
double buffering.
|
||||||
- VST2 editor idle events are now handled slightly differently. This should
|
- VST2 editor idle events are now handled slightly differently. This should
|
||||||
result in even more responsive GUIs for VST2 plugins.
|
result in even more responsive GUIs for VST2 plugins.
|
||||||
- Win32 and X11 events in the Wine plugin host are now handled with lower
|
- Win32 and X11 events in the Wine plugin host are now handled with lower
|
||||||
@@ -71,6 +71,15 @@ TODO: Add an updated screenshot with some fancy VST3-only plugins to the readme
|
|||||||
drawing should not affect DSP load at all, but this should help with less than
|
drawing should not affect DSP load at all, but this should help with less than
|
||||||
optimal setups where some people were getting DSP latency spikes while having
|
optimal setups where some people were getting DSP latency spikes while having
|
||||||
plugin editor open.
|
plugin editor open.
|
||||||
|
- Yabridge handles realtime priority now slightly differently:
|
||||||
|
|
||||||
|
- Realtime priority on the plugin side is now a more granular. Instead of
|
||||||
|
setting everything to use `SCHED_FIFO`, only the spawned threads will be set
|
||||||
|
to realtime priority. This prevents changing the scheduling policy of your
|
||||||
|
host's GUI thread if your host instantiates plugins from its GUI thread like
|
||||||
|
REAPER does.
|
||||||
|
- TODO: Next up is periodically synchronizing audio thread priorities.
|
||||||
|
|
||||||
- Opening and closing plugin editors is now also no longer done with realtime
|
- 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,
|
priority. This should get rid of any latency spikes during those operations,
|
||||||
as this could otherwise steal resources away from the threads that are
|
as this could otherwise steal resources away from the threads that are
|
||||||
|
|||||||
@@ -16,6 +16,7 @@
|
|||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <future>
|
||||||
#include <iomanip>
|
#include <iomanip>
|
||||||
|
|
||||||
// Generated inside of the build directory
|
// Generated inside of the build directory
|
||||||
@@ -88,8 +89,12 @@ class PluginBridge {
|
|||||||
info.windows_plugin_path.string(),
|
info.windows_plugin_path.string(),
|
||||||
.endpoint_base_dir =
|
.endpoint_base_dir =
|
||||||
sockets.base_dir.string()}))),
|
sockets.base_dir.string()}))),
|
||||||
has_realtime_priority(set_realtime_priority(true)),
|
has_realtime_priority(has_realtime_priority_promise.get_future()),
|
||||||
wine_io_handler([&]() { io_context.run(); }) {}
|
wine_io_handler([&]() {
|
||||||
|
has_realtime_priority_promise.set_value(
|
||||||
|
set_realtime_priority(true));
|
||||||
|
io_context.run();
|
||||||
|
}) {}
|
||||||
|
|
||||||
virtual ~PluginBridge(){};
|
virtual ~PluginBridge(){};
|
||||||
|
|
||||||
@@ -108,8 +113,9 @@ class PluginBridge {
|
|||||||
<< "'" << std::endl;
|
<< "'" << std::endl;
|
||||||
init_msg << "plugin type: '" << plugin_type_to_string(info.plugin_type)
|
init_msg << "plugin type: '" << plugin_type_to_string(info.plugin_type)
|
||||||
<< "'" << std::endl;
|
<< "'" << std::endl;
|
||||||
init_msg << "realtime: '" << (has_realtime_priority ? "yes" : "no")
|
init_msg << "realtime: '"
|
||||||
<< "'" << std::endl;
|
<< (has_realtime_priority.get() ? "yes" : "no") << "'"
|
||||||
|
<< std::endl;
|
||||||
init_msg << "sockets: '" << sockets.base_dir.string() << "'"
|
init_msg << "sockets: '" << sockets.base_dir.string() << "'"
|
||||||
<< std::endl;
|
<< std::endl;
|
||||||
init_msg << "wine prefix: '";
|
init_msg << "wine prefix: '";
|
||||||
@@ -300,12 +306,19 @@ class PluginBridge {
|
|||||||
*/
|
*/
|
||||||
std::unique_ptr<HostProcess> plugin_host;
|
std::unique_ptr<HostProcess> plugin_host;
|
||||||
|
|
||||||
|
private:
|
||||||
/**
|
/**
|
||||||
* Whether this process runs with realtime priority. We'll set this _after_
|
* The promise belonging to `has_realtime_priority` below.
|
||||||
* spawning the Wine process because from my testing running wineserver with
|
|
||||||
* realtime priority can actually increase latency.
|
|
||||||
*/
|
*/
|
||||||
bool has_realtime_priority;
|
std::promise<bool> has_realtime_priority_promise;
|
||||||
|
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* Whether this process runs with realtime priority. This is set on the
|
||||||
|
* thread that's relaying STDOUT and STDERR output from Wine, hence the need
|
||||||
|
* for a future.
|
||||||
|
*/
|
||||||
|
std::future<bool> has_realtime_priority;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Runs the Boost.Asio `io_context` thread for logging the Wine process
|
* Runs the Boost.Asio `io_context` thread for logging the Wine process
|
||||||
|
|||||||
@@ -72,6 +72,8 @@ Vst2PluginBridge::Vst2PluginBridge(audioMasterCallback host_callback)
|
|||||||
// instead of asynchronous IO since communication has to be handled in
|
// instead of asynchronous IO since communication has to be handled in
|
||||||
// lockstep anyway
|
// lockstep anyway
|
||||||
host_callback_handler = std::jthread([&]() {
|
host_callback_handler = std::jthread([&]() {
|
||||||
|
set_realtime_priority(true);
|
||||||
|
|
||||||
sockets.vst_host_callback.receive_events(
|
sockets.vst_host_callback.receive_events(
|
||||||
std::pair<Vst2Logger&, bool>(logger, false),
|
std::pair<Vst2Logger&, bool>(logger, false),
|
||||||
[&](Event& event, bool /*on_main_thread*/) {
|
[&](Event& event, bool /*on_main_thread*/) {
|
||||||
|
|||||||
@@ -244,6 +244,8 @@ class Vst3PlugViewProxyImpl : public Vst3PlugViewProxy {
|
|||||||
// to from this thread
|
// to from this thread
|
||||||
std::promise<TResponse> response_promise{};
|
std::promise<TResponse> response_promise{};
|
||||||
std::jthread sending_thread([&]() {
|
std::jthread sending_thread([&]() {
|
||||||
|
set_realtime_priority(true);
|
||||||
|
|
||||||
const TResponse response = bridge.send_message(object);
|
const TResponse response = bridge.send_message(object);
|
||||||
|
|
||||||
// Stop accepting additional work to be run from the calling thread
|
// Stop accepting additional work to be run from the calling thread
|
||||||
|
|||||||
@@ -47,6 +47,8 @@ Vst3PluginBridge::Vst3PluginBridge()
|
|||||||
// first thing, the Wine VST host will ask us for a copy of the
|
// first thing, the Wine VST host will ask us for a copy of the
|
||||||
// configuration.
|
// configuration.
|
||||||
host_callback_handler = std::jthread([&]() {
|
host_callback_handler = std::jthread([&]() {
|
||||||
|
set_realtime_priority(true);
|
||||||
|
|
||||||
sockets.vst_host_callback.receive_messages(
|
sockets.vst_host_callback.receive_messages(
|
||||||
std::pair<Vst3Logger&, bool>(logger, false),
|
std::pair<Vst3Logger&, bool>(logger, false),
|
||||||
overload{
|
overload{
|
||||||
|
|||||||
@@ -21,6 +21,8 @@
|
|||||||
#include <boost/process/io.hpp>
|
#include <boost/process/io.hpp>
|
||||||
#include <boost/process/start_dir.hpp>
|
#include <boost/process/start_dir.hpp>
|
||||||
|
|
||||||
|
#include "src/common/utils.h"
|
||||||
|
|
||||||
namespace bp = boost::process;
|
namespace bp = boost::process;
|
||||||
namespace fs = boost::filesystem;
|
namespace fs = boost::filesystem;
|
||||||
|
|
||||||
@@ -191,6 +193,8 @@ GroupHost::GroupHost(boost::asio::io_context& io_context,
|
|||||||
const pid_t group_host_pid = group_host.id();
|
const pid_t group_host_pid = group_host.id();
|
||||||
group_host_connect_handler =
|
group_host_connect_handler =
|
||||||
std::jthread([this, connect, group_host_pid]() {
|
std::jthread([this, connect, group_host_pid]() {
|
||||||
|
set_realtime_priority(true);
|
||||||
|
|
||||||
using namespace std::literals::chrono_literals;
|
using namespace std::literals::chrono_literals;
|
||||||
|
|
||||||
// We'll first try to connect to the group host we just spawned
|
// We'll first try to connect to the group host we just spawned
|
||||||
|
|||||||
Reference in New Issue
Block a user