Add way to use 32-bit VST3 when both are installed

Otherwise we would always use the 64-bit version and there would be no
way to use the 32-bit version, if version for some reason works better.

Relates to #80.
This commit is contained in:
Robbert van der Helm
2021-04-13 19:27:02 +02:00
parent f177b69aae
commit a297866d45
7 changed files with 67 additions and 38 deletions
+6
View File
@@ -12,6 +12,12 @@ Versioning](https://semver.org/spec/v2.0.0.html).
- Added support for using 32-bit Windows VST3 plugins in 64-bit Linux VST3
hosts.
- Added an
[option](https://github.com/robbert-vdh/yabridge#compatibility-options) to
prefer the 32-bit version of a VST3 plugin over the 64-bit version if both are
installed. This likely won't be necessary, but because of the way VST3 bundles
work there's no clean way to separate these, and when both are installed the
64-bit version gets used by default.
### Fixed
+1
View File
@@ -308,6 +308,7 @@ plugin._
| `editor_xembed` | `{true,false}` | Use Wine's XEmbed implementation instead of yabridge's normal window embedding method. Some plugins will have redrawing issues when using XEmbed and editor resizing won't always work properly with it, but it could be useful in certain setups. You may need to use [this Wine patch](https://github.com/psycha0s/airwave/blob/master/fix-xembed-wine-windows.patch) if you're getting blank editor windows. Defaults to `false`. |
| `frame_rate` | `<number>` | The rate at which Win32 events are being handled and usually also the refresh rate of a plugin's editor GUI. When using plugin groups all plugins share the same event handling loop, so in those the last loaded plugin will set the refresh rate. Defaults to `60`. |
| `vst3_no_scaling` | `{true,false}` | Disable HiDPI scaling for VST3 plugins. Wine currently does not have proper fractional HiDPI support, so you might have to enable this option if you're using a HiDPI display. In most cases setting the font DPI in `winecfg`'s graphics tab to 192 will cause plugins to scale correctly at 200% size. Defaults to `false`. |
| `vst3_prefer_32bit` | `{true,false}` | Use the 32-bit version of a VST3 plugin instead the 64-bit version if both are installed and they're in the same VST3 bundle inside of `~/.vst3/yabridge`. You likely won't need this. |
These options are workarounds for issues mentioned in the [known
issues](#runtime-dependencies-and-known-issues) section. Depending on the hosts
+6
View File
@@ -125,6 +125,12 @@ Configuration::Configuration(const fs::path& config_path,
} else {
invalid_options.push_back(key);
}
} else if (key == "vst3_prefer_32bit") {
if (const auto parsed_value = value.as_boolean()) {
vst3_prefer_32bit = parsed_value->get();
} else {
invalid_options.push_back(key);
}
} else {
unknown_options.push_back(key);
}
+10
View File
@@ -142,6 +142,15 @@ class Configuration {
*/
bool vst3_no_scaling = false;
/**
* If a merged bundle contains both the 64-bit and the 32-bit versions of a
* Windows VST3 plugin (in the `x86_64-win` and the `x86-win` directories),
* then yabridge will use the 64-bit version by default. This option
* overrides that preference and thus allows you to use the 32-bit version
* if that's for whatever reason necessary.
*/
bool vst3_prefer_32bit = false;
/**
* The name of the plugin group that should be used for the plugin this
* configuration object was created for. If not set, then the plugin should
@@ -187,6 +196,7 @@ class Configuration {
s.ext(frame_rate, bitsery::ext::StdOptional(),
[](S& s, auto& v) { s.value4b(v); });
s.value1b(vst3_no_scaling);
s.value1b(vst3_prefer_32bit);
s.ext(group, bitsery::ext::StdOptional(),
[](S& s, auto& v) { s.text1b(v, 4096); });
+15 -12
View File
@@ -59,12 +59,12 @@ class PluginBridge {
*/
template <typename F>
PluginBridge(PluginType plugin_type, F create_socket_instance)
: info(plugin_type),
io_context(),
sockets(create_socket_instance(io_context, info)),
// This is still correct for VST3 plugins because we can configure an
// entire directory (the module's bundle) at once
config(load_config_for(info.native_library_path)),
: config(load_config_for(get_this_file_location())),
info(plugin_type, config.vst3_prefer_32bit),
io_context(),
sockets(create_socket_instance(io_context, info)),
generic_logger(Logger::create_from_environment(
create_logger_prefix(sockets.base_dir))),
plugin_host(
@@ -196,6 +196,9 @@ class PluginBridge {
if (config.vst3_no_scaling) {
other_options.push_back("vst3: no GUI scaling");
}
if (config.vst3_prefer_32bit) {
other_options.push_back("vst3: prefer 32-bit");
}
if (!other_options.empty()) {
init_msg << join_quoted_strings(other_options) << std::endl;
} else {
@@ -279,6 +282,14 @@ class PluginBridge {
#endif
}
/**
* The configuration for this instance of yabridge. Set based on the values
* from a `yabridge.toml`, if it exists.
*
* @see ../utils.h:load_config_for
*/
Configuration config;
/**
* Information about the plugin we're bridging.
*/
@@ -296,14 +307,6 @@ class PluginBridge {
*/
TSockets sockets;
/**
* The configuration for this instance of yabridge. Set based on the values
* from a `yabridge.toml`, if it exists.
*
* @see ../utils.h:load_config_for
*/
Configuration config;
/**
* The logging facility used for this instance of yabridge. See
* `Logger::create_from_env()` for how this is configured.
+24 -19
View File
@@ -36,21 +36,23 @@ namespace fs = boost::filesystem;
// docstrings for the corresponding fields for more information on what we're
// actually doing here.
fs::path find_plugin_library(const fs::path& this_plugin_path,
PluginType plugin_type);
PluginType plugin_type,
bool prefer_32bit_vst3);
fs::path normalize_plugin_path(const fs::path& windows_library_path,
PluginType plugin_type);
std::variant<OverridenWinePrefix, fs::path, DefaultWinePrefix> find_wine_prefix(
fs::path windows_plugin_path);
PluginInfo::PluginInfo(PluginType plugin_type)
PluginInfo::PluginInfo(PluginType plugin_type, bool prefer_32bit_vst3)
: plugin_type(plugin_type),
native_library_path(get_this_file_location()),
// As explained in the docstring, this is the actual Windows library. For
// VST3 plugins that come in a module we should be loading that module
// instead of the `.vst3` file within in, which is where
// `windows_plugin_path` comes in.
windows_library_path(
find_plugin_library(native_library_path, plugin_type)),
windows_library_path(find_plugin_library(native_library_path,
plugin_type,
prefer_32bit_vst3)),
plugin_arch(find_dll_architecture(windows_library_path)),
windows_plugin_path(
normalize_plugin_path(windows_library_path, plugin_type)),
@@ -88,7 +90,8 @@ boost::filesystem::path PluginInfo::normalize_wine_prefix() const {
}
fs::path find_plugin_library(const fs::path& this_plugin_path,
PluginType plugin_type) {
PluginType plugin_type,
bool prefer_32bit_vst3) {
switch (plugin_type) {
case PluginType::vst2: {
fs::path plugin_path(this_plugin_path);
@@ -141,29 +144,31 @@ fs::path find_plugin_library(const fs::path& this_plugin_path,
// Finding the Windows plugin consists of two steps because
// Steinberg changed the format around:
// - First we'll find the plugin in the VST3 bundle created by
// yabridgectl in `~/.vst3`. The plugin can be either 32-bit or
// 64-bit.
// TODO: Right now we can't select between the 64-bit and the
// 32-bit version and we'll just pick whichever one is
// available
// yabridgectl in `~/.vst3/yabridge`. The plugin can be either
// 32-bit or 64-bit. If both exist, then we'll take the 64-bit
// version, unless the `vst3_prefer_32bit` yabridge.toml option
// has been enabled for this plugin.
// - After that we'll resolve the symlink to the module in the Wine
// prefix, and then we'll have to figure out if this module is an
// old style standalone module (< 3.6.10) or if it's inside of
// a bundle (>= 3.6.10)
fs::path candidate_path =
const fs::path candidate_path_64bit =
bundle_home / "Contents" / "x86_64-win" / win_module_name;
if (!fs::exists(candidate_path)) {
// Try the 32-bit version no 64-bit version exists (although, is
// there a single VST3 plugin where this is the case?)
candidate_path =
const fs::path candidate_path_32bit =
bundle_home / "Contents" / "x86-win" / win_module_name;
}
// After this we'll have to use `normalize_plugin_path()` to get the
// actual module entry point in case the plugin is using a VST
// 3.6.10 style bundle
if (fs::exists(candidate_path)) {
return fs::canonical(candidate_path);
// 3.6.10 style bundle, because we need to inspect that for the
// _actual_ (with yabridgectl `x86_64-win` should only contain a
// 64-bit plugin and `x86-win` should only contain a 32-bit plugin,
// but you never know!)
if (prefer_32bit_vst3 && fs::exists(candidate_path_32bit)) {
return fs::canonical(candidate_path_32bit);
} else if (fs::exists(candidate_path_64bit)) {
return fs::canonical(candidate_path_64bit);
} else if (fs::exists(candidate_path_32bit)) {
return fs::canonical(candidate_path_32bit);
}
throw std::runtime_error(
+4 -6
View File
@@ -56,19 +56,17 @@ struct PluginInfo {
* we'll have yabridgectl create a 'merged bundle' that also contains the
* Windows VST3 plugin.
*
* TODO: At the moment we can't choose to use the 32-bit VST3 if a 64-bit
* plugin exists. Potential solutions are to add a config option to
* use the 32-bit version, or we can add a filename suffix to all
* 32-bit versions so they can live alongside each other.
*
* @param plugin_type The type of the plugin we're going to load. The
* detection works slightly differently depending on the plugin type.
* @param prefer_32bit_vst3 If there's both a 64-bit and a 32-bit Windows
* VST3 module in the same bundle, then setting this to true will cause
* the 32-bit version to be used instead of the 64-bit version.
*
* @throw std::runtime_error If we cannot find a corresponding Windows
* plugin. The error message contains a human readable description of what
* went wrong.
*/
PluginInfo(PluginType plugin_type);
PluginInfo(PluginType plugin_type, bool prefer_32bit_vst3 = false);
/**
* Create the environment for the plugin host based on `wine_prefix`. If