Instead of a VST3-style polling function to test if a plugin supports a
certain layout, the plugin now explicitly enumerates the supported
layouts. This aligns better with non-VST3 plugin formats.
I've been putting this off for a while, but now is finally the day. We
already did this for CLAP a while back. This is both simpler and less
error prone.
This is needed to enable sending and receiving SysEx #54. Because
associated type defaults still are not stable, this requires every
plugin that doesn't need this to set this to the unit type:
```rust
type SysExMessage = ();
```
This will make it possible to run background tasks in a type safe way.
Sadly, this does mean that every plugin now needs to define the type
alias and constructor function since Rust does not yet support defaults
for associated types.
This can now be used for most common use cases where you previously had
to do a manual `Params` implementation, like arrays of parameter objects
and duplicate parameter objects.
The missing parts are allocating buffers for these busses, copying data
to those buffers, and adding methods to the ProcessContext to interact
with these inputs and outputs.
This is a breaking change requiring a small change to plugin
implementations.
The reason why `Pin<&dyn Params>` was used was more as a hint to
indicate that the object must last for the plugin's lifetime, but `Pin`
doesn't enforce that. It also makes the APIs a lot more awkward.
Requiring the use of `Arc` fixes the following problems:
- When storing the params object in the wrapper, the `ParamPtr`s are
guaranteed to be stable.
- This makes it possible to access the `Params` object without acquiring
a lock on the plugin, this is very important for implementing
plugin-side preset management.
- It enforces immutability on the `Params` object.
- And of course the API is much nicer without a bunch of unsafe code to
work around Pin's limitations.
They are now two separate types with slightly different options. I had
these merged initially because they're 95% the same, and I thought it
would be fun to have weird distributions for integer parameters, but
that doesn't really work because hosts and the plugin APIs expect the
steps to be linear. And if you're going to have an unstepped integer
parameter, might as well use FloatParam with rounding.
Because non-linear ranges are no longer possible with IntParam, the
types have been split up to make everything much more readable instead
of adding a parameterizing the range type with another type family.