These critical notifications don't expire under KDE Plasma, which would
mean that you'd get absolutely flooded with notifications you have to
manually close when something is wrong.
This makes the initialization message reflect the correct Wine version
when using a `WINELOADER` script to change between Wine versions
depending on the Wine prefix.
Ardour apparently always calls `effMainsChanged()` with a value argument
of 0 when unloading the plugin, regardless of whether it has actually
initialized audio processing before that point.
In the same way as 50c25c1cf0 did it for
VST2 plugins. Input and output audio data is now stored in a shared
memory buffer instead of being sent over the sockets. This reduces the
bridging overhead to a minimum since copying data was the most expensive
operation we were doing and we now only need to copy the entire buffer
once per processing cycle.
We now use shared memory to store the input and output audio buffers.
This means that we have to copy less data every processing cycle, since
a single copy to and a single copy from the shared memory object
suffices now. This should reduce the DSP load for VST2
plugins (especially when used in a plugin group) marginally to
significantly depending on the plugins used and the system
configuration.
Every DAW will just send all events in one go (and I think that's the
only way you should do it, but the VST2 spec is a bit leaky so who
knows). It wouldn't make much sense to preallocate more capacity,
because when DAWs do send all of those events individually they might
end up sending more than four of these anyways.
I once read years ago somewhere on Stack Overflow that `std::vectors`
with that are preinitialized to a default size would allocate the
initial capacity on the stack. This of course doesn't make any
sense (run time sized stack allocations can cause all kinds of issues),
so we were still allocating with our default 64-byte sized buffers, but
just not as often.
C++ would always construct an `std::string` from the string constant
every iteration. Since this also happened when `YABRIDGE_DEBUG_LEVEL` is
not set to 2, this ended up causing unnecessary allocations.
This does what we did for a few functions in the last few commits for
every function. We now use either the `std::invocable` concept or our
own `invocable_returning` concept wherever possible to make sure we pass
function types to these template functions, since constraint errors are
a lot more readable than template deduction errors. And instead of
having to specify the return type as a template argument, we now just
use `std::invoke_result_t<F>` instead. The VST3 message handling
functions are still using the good old `typename F` since those are
overloaded polymorphic functions. This was also a good moment to modify
`AdHocSocketHandler::send()` to allow functions returning void (this got
rid of an old fixme where we had to return some dummy value from a
function instead of just not returning anything).
For some reason ujam plugins (and other plugins made with the Gorilla
Engine, like the LoopCloud plugins) will throw a `JS_EXEC_FAILED` error
when trying to load the plugin while either of the STDOUT or STDERR
streams is pointing to a pipe. Simply redirecting the output to a file
fixes this. By default we'll write the output to
`<temporary_directory>/yabridge-plugin-output.log`, but you can also set
the new `disable_pipes` option to `"/dev/null"` to completely throw away
all output.
This addresses #47.
This may also fix some weird cases where everything appeared to work
fine, but where the file descriptors weren't actually assigned
correctly. Not sure what that happened, but it with carla-single the
Wine host's STDOUT and STDERR would still point to the orignal pty even
though everything still went through the pipes.
With `vfork()` the child process inherits the parents process image and
prevents copying them, but if it outlives its parent then the file
descriptors will still remain open. Manually closing all file
descriptors is the only solution here.
This was only an issue with Ardour since they don't open all of their
files with `FD_CLOEXEC`. Last update's watchdog timer somewhat mitigated
the issue, but Ardour should now no longer freeze when reopening because
of this. The watchdog timer is still necessary, since hanging Wine
processes will still prevent the Wine server from shutting down.
This makes much more sense, since all plugin instances will be sharing a
single GUI thread. What would happen was that resize calls from one
instance and GUI thread function calls from another instance would
collide. Using a single shared mutual recursion mechanism (just like on
the Wine side) fixes this.
This was causing a timing issue with DMG plugins where the plugins would
try to resize after receiving new state (and not during the call), while
REAPER at the same time would try to set channel context information on
the plugin (which also has to be handled on the GUI thread).
This is very ugly so hopefully I can think of a neater way, but now the
response object is just a set of pointers, so we can avoid all copies
and moves on the Wine side.