From 920a6a46c35d2fb7fad6faa5824085d9b258d5a5 Mon Sep 17 00:00:00 2001 From: Robin Gareus Date: Fri, 7 Jul 2023 21:32:33 +0200 Subject: [PATCH] VST3: work around UADx crash when in mono configuration When using a UADx plugin on a Mono track in Ardour, the plugin is configured to be Mono. by calling `setBusArrangements`. The call succeeds and querying the Bus layout via `getBusArrangement` as suggested by https://steinbergmedia.github.io/vst3_doc/vstinterfaces/classSteinberg_1_1Vst_1_1IAudioProcessor.html#ad3bc7bac3fd3b194122669be2a1ecc42 confirms this. The plugin acknowledges the speaker layout for both input and output (Vst::SpeakerArr::kMono = 0x80000) ``` Input BusArrangements: 0 chan: 1 bits: 80000 Output BusArrangements: 0 chan: 1 bits: 80000 ``` but UADx plugins crash later during process() if any of the lower bits are unset and the bus is enabled. PS. The plugin does NOT crash as long as a lower bit (Vst::SpeakerArr::kSpeakerL or ::kSpeakerR) remains set in addition to kMono. --- libs/ardour/ardour/vst3_plugin.h | 3 +++ libs/ardour/vst3_plugin.cc | 15 +++++++++++++-- 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/libs/ardour/ardour/vst3_plugin.h b/libs/ardour/ardour/vst3_plugin.h index 3cad78d02d..4e270ba03c 100644 --- a/libs/ardour/ardour/vst3_plugin.h +++ b/libs/ardour/ardour/vst3_plugin.h @@ -332,6 +332,9 @@ private: int _n_midi_inputs; int _n_midi_outputs; int _n_factory_presets; + + /* work around UADx plugin crash */ + bool _no_kMono; }; } // namespace Steinberg diff --git a/libs/ardour/vst3_plugin.cc b/libs/ardour/vst3_plugin.cc index 3dca859f9b..b28ffe4a76 100644 --- a/libs/ardour/vst3_plugin.cc +++ b/libs/ardour/vst3_plugin.cc @@ -1161,6 +1161,7 @@ VST3PI::VST3PI (std::shared_ptr m, std::string unique_ , _owner (0) , _add_to_selection (false) , _n_factory_presets (0) + , _no_kMono (false) { using namespace std; IPluginFactory* factory = m->factory (); @@ -1173,6 +1174,16 @@ VST3PI::VST3PI (std::shared_ptr m, std::string unique_ throw failed_constructor (); } + PFactoryInfo fi; + if (factory->getFactoryInfo (&fi) == kResultTrue) { + /* work around issue with UADx VST3s not recognizing + * Vst::SpeakerArr::kMono. (see commit message for details) + */ + if (0 == strcmp (fi.vendor, "Universal Audio (UADx)")) { + _no_kMono = true; + } + } + #ifndef NDEBUG if (DEBUG_ENABLED (DEBUG::VST3Config)) { char fuid[33]; @@ -2210,7 +2221,7 @@ VST3PI::enable_io (std::vector const& ins, std::vector const& outs) } cnt += n_chn; /* special case for Left only == Mono */ - if (sa == 1 /*Vst::SpeakerArr::kSpeakerL */) { + if (sa == 1 /*Vst::SpeakerArr::kSpeakerL */ && !_no_kMono) { sa = Vst::SpeakerArr::kMono; /* 1 << 19 */ } @@ -2234,7 +2245,7 @@ VST3PI::enable_io (std::vector const& ins, std::vector const& outs) } cnt += n_chn; /* special case for Left only == Mono */ - if (sa == 1 /*Vst::SpeakerArr::kSpeakerL */) { + if (sa == 1 /*Vst::SpeakerArr::kSpeakerL */ && !_no_kMono) { sa = Vst::SpeakerArr::kMono; /* 1 << 19 */ } DEBUG_TRACE (DEBUG::VST3Config, string_compose ("VST3PI::enable_io: activateBus (kAudio, kOutput, %1, %2) used-chn: %3 spk-arr: %4\n", sa_out.size (), enable, _bus_info_out[sa_out.size ()].n_used_chn, std::hex, sa));