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.
This commit is contained in:
Robin Gareus 2023-07-07 21:32:33 +02:00
parent 4fc3bd88aa
commit 920a6a46c3
Signed by: rgareus
GPG Key ID: A090BCE02CF57F04
2 changed files with 16 additions and 2 deletions

View File

@ -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

View File

@ -1161,6 +1161,7 @@ VST3PI::VST3PI (std::shared_ptr<ARDOUR::VST3PluginModule> 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<ARDOUR::VST3PluginModule> 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<bool> const& ins, std::vector<bool> 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<bool> const& ins, std::vector<bool> 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));