mirror of
https://github.com/robbert-vdh/yabridge.git
synced 2026-05-07 03:50:11 +02:00
Allow hiding the DAW name for VST2 plugins
This can be useful when plugins have (broken) host-specific behaviour that you want to avoid. I'll later add a list of host/plugin combinations where this may be useful to the readme.
This commit is contained in:
@@ -8,6 +8,15 @@ Versioning](https://semver.org/spec/v2.0.0.html).
|
||||
|
||||
## [Unreleased]
|
||||
|
||||
### Added
|
||||
|
||||
- Added a new [compatibility
|
||||
option](https://github.com/robbert-vdh/yabridge#compatibility-options) to hide
|
||||
the name of the DAW you're using for a plugin. This can be useful with plugins
|
||||
that have undesirable or broken DAW-specific behaviour. See the [known
|
||||
issues](https://github.com/robbert-vdh/yabridge#runtime-dependencies-and-known-issues)
|
||||
section of the readme for more information on when this may be useful.
|
||||
|
||||
### Changed
|
||||
|
||||
- When building the package from source, the targetted Wine version gets printed
|
||||
|
||||
@@ -297,6 +297,7 @@ plugin._
|
||||
| `editor_force_dnd` | `{true,false}` | This option forcefully enables drag-and-drop support in _REAPER_. Because REAPER's FX window supports drag-and-drop itself, dragging a file onto a plugin editor will cause the drop to be intercepted by the FX window. This makes it impossible to drag files onto plugins in REAPER under normal circumstances. Setting this option to `true` will strip drag-and-drop support from the FX window, thus allowing files to be dragged onto the plugin again. Defaults to `false`. |
|
||||
| `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`. |
|
||||
| `hide_daw` | `{true,false}` | Don't report the name of the actual DAW to the plugin. See the [known issues](#runtime-dependencies-and-known-issues) section for a list of situations where this may be useful. This affects both VST2 and VST3 plugins. Defaults to `false`. |
|
||||
| `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. |
|
||||
|
||||
@@ -329,6 +330,9 @@ editor_double_embed = true
|
||||
["Analog Lab 3.so"]
|
||||
editor_xembed = true
|
||||
|
||||
["Chromaphone 3.so"]
|
||||
hide_daw = true
|
||||
|
||||
["SWAM Cello 64bit.so"]
|
||||
cache_time_info = true
|
||||
|
||||
@@ -367,6 +371,9 @@ deep within in, like this:
|
||||
group = "fabfilter"
|
||||
vst3_no_scaling = true
|
||||
|
||||
["Chromaphone 3.vst3"]
|
||||
hide_daw = true
|
||||
|
||||
["Misstortion2.vst3"]
|
||||
vst3_no_scaling = true
|
||||
|
||||
|
||||
@@ -119,6 +119,12 @@ Configuration::Configuration(const fs::path& config_path,
|
||||
} else {
|
||||
invalid_options.push_back(key);
|
||||
}
|
||||
} else if (key == "hide_daw") {
|
||||
if (const auto parsed_value = value.as_boolean()) {
|
||||
hide_daw = parsed_value->get();
|
||||
} else {
|
||||
invalid_options.push_back(key);
|
||||
}
|
||||
} else if (key == "vst3_no_scaling") {
|
||||
if (const auto parsed_value = value.as_boolean()) {
|
||||
vst3_no_scaling = parsed_value->get();
|
||||
|
||||
@@ -138,6 +138,15 @@ class Configuration {
|
||||
*/
|
||||
std::optional<float> frame_rate;
|
||||
|
||||
/**
|
||||
* When this option is enabled, we'll report some random other string
|
||||
* instead of the actual name of the host when the plugin queries it. This
|
||||
* can sometimes be useful when a plugin has undesirable host-specific
|
||||
* behaviour. See the readme for some examples of where this might be
|
||||
* useful.
|
||||
*/
|
||||
bool hide_daw = false;
|
||||
|
||||
/**
|
||||
* Disable `IPlugViewContentScaleSupport::setContentScaleFactor()`. Wine
|
||||
* does not properly implement fractional DPI scaling, so without this
|
||||
@@ -198,6 +207,7 @@ class Configuration {
|
||||
s.value1b(editor_xembed);
|
||||
s.ext(frame_rate, bitsery::ext::StdOptional(),
|
||||
[](S& s, auto& v) { s.value4b(v); });
|
||||
s.value1b(hide_daw);
|
||||
s.value1b(vst3_no_scaling);
|
||||
s.value1b(vst3_prefer_32bit);
|
||||
|
||||
|
||||
@@ -31,6 +31,20 @@
|
||||
*/
|
||||
constexpr time_t audio_thread_priority_synchronization_interval = 10;
|
||||
|
||||
/**
|
||||
* When the `hide_daw` compatibility option is enabled, we'll report this
|
||||
* instead of the actual DAW's name. This can be useful when plugins are
|
||||
* hardcoded to behave differently in certain DAWs, and when that different
|
||||
* behaviour causes issues under Wine. Examples of this are Melodyne 5 under
|
||||
* REAPER, and AAS Chromaphone 3 under Bitwig.
|
||||
*/
|
||||
constexpr char product_name_override[] = "Get yabridge'd";
|
||||
/**
|
||||
* When the `hide_daw` compatibility option is enabled, we'll report this
|
||||
* instead of the actual vendor's name in a VST2 plugin.
|
||||
*/
|
||||
constexpr char vendor_name_override[] = "yabridge";
|
||||
|
||||
// The cannonical overloading template for `std::visitor`, not sure why this
|
||||
// isn't part of the standard library
|
||||
template <class... Ts>
|
||||
|
||||
@@ -193,6 +193,9 @@ class PluginBridge {
|
||||
<< *config.frame_rate << " fps";
|
||||
other_options.push_back(option.str());
|
||||
}
|
||||
if (config.hide_daw) {
|
||||
other_options.push_back("hack: hide DAW name");
|
||||
}
|
||||
if (config.vst3_no_scaling) {
|
||||
other_options.push_back("vst3: no GUI scaling");
|
||||
}
|
||||
|
||||
+44
-11
@@ -90,11 +90,10 @@ Vst2PluginBridge::Vst2PluginBridge(audioMasterCallback host_callback)
|
||||
|
||||
incoming_midi_events.push_back(
|
||||
std::get<DynamicVstEvents>(event.payload));
|
||||
EventResult response{.return_value = 1,
|
||||
.payload = nullptr,
|
||||
.value_payload = std::nullopt};
|
||||
|
||||
return response;
|
||||
return EventResult{.return_value = 1,
|
||||
.payload = nullptr,
|
||||
.value_payload = std::nullopt};
|
||||
} break;
|
||||
// REAPER requires that `audioMasterSizeWindow()` calls are
|
||||
// handled from the GUI thread, which is the thread that
|
||||
@@ -105,16 +104,50 @@ Vst2PluginBridge::Vst2PluginBridge(audioMasterCallback host_callback)
|
||||
std::lock_guard lock(incoming_resize_mutex);
|
||||
|
||||
incoming_resize = std::pair(event.index, event.value);
|
||||
EventResult response{.return_value = 1,
|
||||
.payload = nullptr,
|
||||
.value_payload = std::nullopt};
|
||||
|
||||
return response;
|
||||
return EventResult{.return_value = 1,
|
||||
.payload = nullptr,
|
||||
.value_payload = std::nullopt};
|
||||
} break;
|
||||
// HACK: Certain plugins may have undesirable DAW-specific
|
||||
// behaviour. Chromaphone 3 for instance has broken
|
||||
// text input dialogs when using Bitwig. We can work
|
||||
// around these issues by reporting we're running
|
||||
// under some other host. We need to do this on the
|
||||
// plugin side instead of one the Wine side because
|
||||
// the plugin will likely do this callback during
|
||||
// initialization, and at that point we will not yet
|
||||
// have sent the configuration to the plugin.
|
||||
case audioMasterGetProductString: {
|
||||
if (config.hide_daw) {
|
||||
logger.log("The plugin asked for the host's name.");
|
||||
logger.log("Reporting \"" +
|
||||
std::string(product_name_override) +
|
||||
"\" instead of the actual host's name.");
|
||||
|
||||
return EventResult{.return_value = 1,
|
||||
.payload = product_name_override,
|
||||
.value_payload = std::nullopt};
|
||||
}
|
||||
} break;
|
||||
case audioMasterGetVendorString: {
|
||||
if (config.hide_daw) {
|
||||
logger.log(
|
||||
"The plugin asked for the host's vendor.");
|
||||
logger.log(
|
||||
"Reporting \"" +
|
||||
std::string(vendor_name_override) +
|
||||
"\" instead of the actual host's vendor.");
|
||||
|
||||
return EventResult{.return_value = 1,
|
||||
.payload = vendor_name_override,
|
||||
.value_payload = std::nullopt};
|
||||
}
|
||||
} break;
|
||||
default:
|
||||
return passthrough_event(&plugin,
|
||||
host_callback_function, event);
|
||||
}
|
||||
|
||||
return passthrough_event(&plugin, host_callback_function,
|
||||
event);
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
Reference in New Issue
Block a user