From a0452eeb57d5acf5db795dec5f303038963ba85c Mon Sep 17 00:00:00 2001 From: Robin Gareus Date: Fri, 6 Jan 2023 03:08:05 +0100 Subject: [PATCH] VST3: dynamically grow ParameterChanges Some plugins (e.g. Roland JD-800) have zero controls, but MIDI control with are not directly accounted for. This results in a zero-size ParameterChanges queue, which later produced a segfault when trying to enqueue a MIDI change: ``` input_param_changes.addParameterData (id, index)->addPoint (sample_off, value, index); ``` --- libs/ardour/vst3_host.cc | 17 +++++++++++------ libs/ardour/vst3_plugin.cc | 6 ++++++ 2 files changed, 17 insertions(+), 6 deletions(-) diff --git a/libs/ardour/vst3_host.cc b/libs/ardour/vst3_host.cc index 37ec59554f..78ecbf8b6f 100644 --- a/libs/ardour/vst3_host.cc +++ b/libs/ardour/vst3_host.cc @@ -585,13 +585,18 @@ Vst3ParameterChanges::addParameterData (Vst::ParamID const& pid, int32& index) } } - if (_used_queue_count < (int32)_queue.size ()) { - index = _used_queue_count++; - _queue[index].setParameterId (pid); - return &_queue[index]; + /* some plugins (e.g. Roland JD-800) have zero controls + * (set_n_params (0)) but MIDI controls (which are not accounted for). + * So we grow the list as needed. NB. It is not rt-safe to do so, but it + * only happens once initially. + */ + if (_used_queue_count >= (int32)_queue.size ()) { + _queue.resize (_used_queue_count + 1); } - index = 0; - return 0; + + index = _used_queue_count++; + _queue[index].setParameterId (pid); + return &_queue[index]; } /* ****************************************************************************/ diff --git a/libs/ardour/vst3_plugin.cc b/libs/ardour/vst3_plugin.cc index 362c189964..37fe11f1ba 100644 --- a/libs/ardour/vst3_plugin.cc +++ b/libs/ardour/vst3_plugin.cc @@ -1230,6 +1230,12 @@ VST3PI::VST3PI (boost::shared_ptr m, std::string uniqu _update_ctrl.push_back (false); } + if (_n_midi_inputs > 0 || _n_midi_outputs > 0) { + n_params += 128; + } else if (n_params == 0) { + n_params = 16; /* arbitrary baseline, grows as needed */ + } + _input_param_changes.set_n_params (n_params); _output_param_changes.set_n_params (n_params);