Commit Graph

245 Commits

Author SHA1 Message Date
Robbert van der Helm 0b9a16cf40 Change the naming scheme for class field members
I'm not a fan of Hungarian notation, but C++ kind of needs it with its
implicit `this`. And of all the common options for this, I find
suffixing members with an underscore the least offensive one.
2022-01-01 21:07:17 +01:00
Robbert van der Helm e0ab24e645 Update copyright headers
Happy new year!
2022-01-01 18:32:10 +01:00
Robbert van der Helm 1507e4f574 Use multiple reader single writer locks for VST3
This would also need to be done on the plugin side.
2021-12-28 18:51:14 +01:00
Robbert van der Helm 2137d79229 Disconnect the correct connection point proxy 2021-12-28 17:09:36 +01:00
Robbert van der Helm 5b3210eed6 Inhibit event loop during VST3 offline processing
This prevents T-RackS 5 from causing the export in Bitwig Studio 4.1.0
beta 2 to freeze.
2021-11-10 21:29:40 +01:00
Robbert van der Helm 2e6732c0e2 Fix regression for VST3 editor initial sizing
We accidentally reverted a little bit too much code in
762e622416. This didn't appear any sooner
because plugins are supposed to call `IPlugFrame::resizeView()` during
`IPlugView::attached()`, so this only affects plugins that don't confirm
to the spec.
2021-08-02 14:47:21 +02:00
Robbert van der Helm c98a9519fe Handle X11 events within the Win32 event loop
This unifies event handling and it allows X11 events to still be
processed even when the event loop is blocked.
2021-07-31 15:19:44 +02:00
Robbert van der Helm 762e622416 Revert "Inhibit the event loop during VST3 editor init"
This reverts commit ff76e482f2.

This was a workaround for a race condition in Nimble Kick when opening
the editor while the plugin has not yet been authorized (a Win32 timer
proc between `IEditController::createView()` and `IPlugView::attached()`
would cause a stack overflow because the plugin doesn't check if the
things it wants to use have actually been initialized yet).

But as it turns out, Bitwig Studio now calls
`IEditController::createView()` unconditionally when loading a VST3
plugin, regardless of whether the user wants to open the editor or not.
So this workaround would cause the message loop to be stalled
indefinitely until you open the editor. Since this would also cause
Nimble Kick to break in the Windows version of Bitwig, we'll simply
revert this workaround. If you need to activate the plugin on Linux, you
can load it in the Windows version of REAPER running under Wine instead.
After that the plugin will work just fine under yabridge.
2021-07-29 13:56:26 +02:00
Robbert van der Helm d13f39dce5 Don't check result on IPlugView::onSize()
Melda plugins always return `kResultFalse`, so we should just assume the
resize succeeds.
2021-07-21 20:45:04 +02:00
Robbert van der Helm e223c98b0d Remove XEmbed testing todo
Still seems to work 'fine' (as in, not really).
2021-07-21 17:01:02 +02:00
Robbert van der Helm e28bc63f8d Also resize the wrapper window for VST3 plugins 2021-07-21 17:01:02 +02:00
Robbert van der Helm 4277561aa4 Reorder Vst3Bridge methods 2021-07-21 17:01:02 +02:00
Robbert van der Helm ff76e482f2 Inhibit the event loop during VST3 editor init
This should in theory prevent Nimble Kick from triggering a stack
overflow when the event loop timer procs before `IPlugView::attached()`
gets called and the plugin hasn't been registered yet. I haven't seen
any other VST3 plugins trigger a race condition here.
2021-07-20 16:24:25 +02:00
Robbert van der Helm 22be79aa0d Move X11 event tracing behind +editor debug flag 2021-07-20 03:15:39 +02:00
Robbert van der Helm 5f7fb2e2c3 Work around thread safety issue in Melda plugins
This is super difficult to trigger on purpose, but I did run into it at
least once just now so it seems like a good idea to at least make sure
that this doesn't happen.
2021-07-15 15:45:15 +02:00
Robbert van der Helm f02341e77f Fix focus handling when reopening REAPER FX window
REAPER initializes the plugin's editor first before reparenting the
parent window to the FX window, so our `topmost_window` didn't actually
refer to the FX window.
2021-07-15 14:21:50 +02:00
Robbert van der Helm f292158889 Silence some more clangd warnings 2021-07-14 17:11:27 +02:00
Robbert van der Helm 5fc7acccd1 Show a notification on version mismatch
Between the plugin and the Wine plugin host application.
2021-07-13 22:14:31 +02:00
Robbert van der Helm 1397400155 Reload supported interfaces after IPluginBase::initialize()
This is needed as a workaround to support Waves VST3 plugins.

Right now does does not actually fix the issue because the arguments are
not updated in the subclasses. The next commit will fix this.
2021-07-05 16:08:01 +02:00
Robbert van der Helm 3fbb01f225 Move all casted VST3 plugin interfaces to struct
To make Waves plugins happy we're going to have to replace this after
calling `IPluginBase::initialize()`.
2021-07-05 15:22:47 +02:00
Robbert van der Helm 97ff407ef6 Allow plug view creation to fail 2021-07-05 15:02:36 +02:00
Robbert van der Helm 4c24baa3d2 Remove default constructor for Vst3PluginInstance
Seems weird to need this specifically so we can use the map overload
that creates a new instance when the key doesn't exist in the map. This
seems safer.
2021-07-05 14:35:44 +02:00
Robbert van der Helm e25231c2d2 Rename VST3 instance holder classes
We're going to have to split up the interfaces into another object so we
can reinitialize it later.
2021-07-05 14:16:23 +02:00
Hector Martin 51ba93e4ed Add missing <bitset> include 2021-06-26 12:29:45 +02:00
Robbert van der Helm 94ba58a7a5 Remove automatically added using std::endl;
This is the first thing you disable on clangd, but apparently I was too
late here.
2021-06-26 12:27:05 +02:00
Robbert van der Helm 42e1e49ab9 Remove debug prints 2021-06-13 00:27:24 +02:00
Robbert van der Helm 9c30d64975 Fix speaker arrangement bitsets
The sizes were wrong, and Blue Cat Audio's VST3 plugins seem to use the
upper bits to store the channel configuration, which thus got read out
incorrectly.
2021-06-11 17:22:46 +02:00
Robbert van der Helm dec19dc12a 💥 Reimplement VST3 audio processing
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.
2021-06-11 13:59:37 +02:00
Robbert van der Helm 14e3ed2cd3 Add shared audio buffers config to IAudioProcessor::setupProcessing() 2021-06-10 21:37:42 +02:00
Robbert van der Helm da5f6e9e7d Always initialize Microsoft COM unconditionally 2021-06-07 22:24:48 +02:00
Robbert van der Helm a7496fae77 Add thread names 2021-06-06 23:45:47 +02:00
Robbert van der Helm 712ef41a7f Make realtime scheduling less aggressive
On the Wine side. Instead of always having it enabled and disabling it
when it could potentially hurt (i.e. when handling GUI related things),
we'll now only enable it when it's potentially beneficial. This way we
don't have to constantly switch scheduling policies on the GUI thread.
2021-06-01 16:21:38 +02:00
Robbert van der Helm e0efa48aa8 Get rid of redundant string conversion
Not sure how this snuck in there.
2021-05-23 19:44:14 +02:00
Robbert van der Helm e4ca520b64 💥 Redo all higher order template functions
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).
2021-05-20 01:03:58 +02:00
Robbert van der Helm 57d7141681 Remove redundant template arguments in MainContext 2021-05-19 22:56:37 +02:00
Robbert van der Helm a9643577fd Also add noexcept qualifications on the Wine side
See the last few commits.
2021-05-14 18:27:19 +02:00
Robbert van der Helm db6ecdbbd4 Also define the shobjidl.h define globally
This was needed for Wine 6.2.
2021-05-11 02:27:43 +02:00
Robbert van der Helm f1d7b7bf57 Avoid allocations in VST3 process response
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.
2021-05-07 19:24:28 +02:00
Robbert van der Helm 93b8643cba Avoid allocations when reconstructing process data 2021-05-07 18:21:30 +02:00
Robbert van der Helm fcaac219a6 💥 Reduce allocations in VST3 audio sockets
We do this by using this new `MessageReference<T>` type to avoid copying
our `YaAudioProcessor::Process` struct and the contained `YaProcessData`
object. This is only part of the work, but this redesign lets us keep
the these objects alive on both the plugin and the host side. On the
plugin side, we'll simply serialize the data from the referred to object
without copying it. On the Wine side, we'll write the data to a
persistent thread local object, and then reassign the
`MessageReference<T>` to point to that object. This lets us serialize
'references', thus avoiding potentially expensive allocations. With
these last few changes alone VST3 plugins are already at the same
performance level as our optimized VST2 plugin groups.
2021-05-07 16:32:08 +02:00
Robbert van der Helm 5c88140c54 Also use mutual recursion for program list changes
The VST3 version of Voxengo TEOTE would deadlock in Ardour when Ardour
calls `IEditController::setState()`, the plugin calls
`IUnitHandler::notifyProgramListChange()` in response, and then when
Ardour calls `IUnitInfo::getProgramName()` while handling that callback.
All of these functions have to be called from the same thread in Voxengo
plugins.
2021-05-02 00:41:28 +02:00
Robbert van der Helm 832089d4d1 Implement the Wine host process watchdog
This will shut down a bridge's sockets when the connected native host
process exits, to prevent dangling Wine processes.
2021-05-01 17:54:22 +02:00
Robbert van der Helm d8ca4022d1 Add universal way to shutdown sockets on Wine side 2021-05-01 16:51:55 +02:00
Robbert van der Helm b22f207aee Move the MainContext to HostBridge
We'll use this to create a watchdog timer that shuts down the sockets
when the native host gets terminated.
2021-05-01 15:06:13 +02:00
Robbert van der Helm 177431e202 Fix performEdit() deadlock in Ardour/Mixbus
Those DAWs would immediately call `IEditController::performEdit()` with
the same parameter change the plugin has just announced, which would
result in a deadlock. Hopefully this helps with #100.
2021-04-30 20:50:54 +02:00
Robbert van der Helm 36b3636072 Handle mutual recursion in context menus
REAPER will call `getState()` while the context menu is open, and that
also has to be handled from the GUI thread.
2021-04-30 02:49:54 +02:00
Robbert van der Helm cb07fd07a2 Handle mutual recursion while loading presets 2021-04-29 23:40:42 +02:00
Robbert van der Helm 0f506f75e4 Bypass connection point proxies when possible
This greatly improves compatibility with VST3 plugins in Ardour and
Mixbus. Most notably the FabFilter plugins would previously freeze when
having the GUI open while duplicating or inserting new instances.
2021-04-29 15:36:28 +02:00
Robbert van der Helm e4177f2856 Avoid IAudioProcessor::isActive() on GUI thread
I haven't seen this cause any issues this way, and I could imagine that
this could cause some hangs when initializing a second instance of a
plugin while you're interacting with the GUI of the first instance.
2021-04-29 14:29:15 +02:00
Robbert van der Helm a56e4b337f Rename the VST3 mutual recursion functions 2021-04-29 14:03:15 +02:00