From c51e3ac7c783f30d8e465ef937fcaf49f4d28aeb Mon Sep 17 00:00:00 2001 From: Robin Gareus Date: Thu, 24 Sep 2020 15:57:14 +0200 Subject: [PATCH] VST3: support non-integer indexed presets --- libs/ardour/ardour/vst3_plugin.h | 6 +++++- libs/ardour/vst3_plugin.cc | 34 ++++++++++++++++++++++++-------- 2 files changed, 31 insertions(+), 9 deletions(-) diff --git a/libs/ardour/ardour/vst3_plugin.h b/libs/ardour/ardour/vst3_plugin.h index 8f666dc475..4e38dc23b2 100644 --- a/libs/ardour/ardour/vst3_plugin.h +++ b/libs/ardour/ardour/vst3_plugin.h @@ -86,6 +86,7 @@ public: Vst::IUnitInfo* unit_info (); FUID const& fuid() const { return _fuid; } Vst::ParameterInfo const& program_change_port() const { return _program_change_port; } + void set_n_factory_presets (size_t n) { _n_factory_presets = n; } /* API for Ardour -- Ports */ uint32_t designated_bypass_port () const { return _port_id_bypass; } @@ -97,7 +98,7 @@ public: void get_parameter_descriptor (uint32_t, ARDOUR::ParameterDescriptor&) const; std::string print_parameter (uint32_t p) const; std::string print_parameter (Vst::ParamID, Vst::ParamValue) const; - bool set_program (float p, int32 sample_off, bool normalized); + bool set_program (int p, int32 sample_off); ARDOUR::Plugin::IOPortDescription describe_io_port (ARDOUR::DataType dt, bool input, uint32_t id) const; @@ -217,6 +218,7 @@ private: int _n_aux_outputs; int _n_midi_inputs; int _n_midi_outputs; + int _n_factory_presets; }; } // namespace Steinberg @@ -297,6 +299,8 @@ private: Steinberg::VST3PI* _plug; PBD::ScopedConnectionList _connections; + + int32_t _factory_preset_count; std::map _preset_uri_map; std::vector _connected_inputs; diff --git a/libs/ardour/vst3_plugin.cc b/libs/ardour/vst3_plugin.cc index 7909b1c0ae..e57fd22fe0 100644 --- a/libs/ardour/vst3_plugin.cc +++ b/libs/ardour/vst3_plugin.cc @@ -325,7 +325,7 @@ VST3PI::evoral_to_vst3 (Vst::Event& e, Evoral::Event const& ev, int return false; case MIDI_CMD_PGM_CHANGE: assert (size == 2); - set_program (data2 / 127.f, ev.time (), true); // TODO map to available programs ?! + set_program (data2, ev.time ()); return false; case MIDI_CMD_CHANNEL_PRESSURE: assert (size == 2); @@ -687,7 +687,7 @@ VST3Plugin::load_preset (PresetRecord r) if (tmp[0] == "VST3-P") { int program = PBD::atoi (tmp[2]); assert (!r.user); - if (!_plug->set_program (program, 0, false)) { + if (!_plug->set_program (program, 0)) { #ifndef NDEBUG std::cerr << "set_program failed\n"; #endif @@ -764,7 +764,6 @@ static bool vst3_preset_filter (const std::string& str, void*) void VST3Plugin::find_presets () { - _presets.clear (); _preset_uri_map.clear (); @@ -828,6 +827,8 @@ VST3Plugin::find_presets () } } + _plug->set_n_factory_presets (_presets.size ()); + // TODO check _plug->unit_data() // IUnitData: programDataSupported -> setUnitProgramData (IBStream) @@ -947,6 +948,7 @@ VST3PI::VST3PI (boost::shared_ptr m, std::string uniqu , _is_processing (false) , _block_size (0) , _port_id_bypass (UINT32_MAX) + , _n_factory_presets (0) { using namespace std; @@ -1530,16 +1532,32 @@ VST3PI::set_parameter (uint32_t p, float value, int32 sample_off) } bool -VST3PI::set_program (float value, int32 sample_off, bool normalized) +VST3PI::set_program (int pgm, int32 sample_off) { if (_program_change_port.id == Vst::kNoParamId) { return false; } - Vst::ParamID id = _program_change_port.id; - - if (!normalized) { - value = _controller->plainParamToNormalized (id, value); + if (_n_factory_presets < 1) { + return false; } + + if (pgm < 0 || pgm >= _n_factory_presets) { + return false; + } + + Vst::ParamID id = _program_change_port.id; +#if 0 + /* This fails with some plugins (e.g. waves.vst3), + * that do not use integer indexed presets. + */ + float value = _controller->plainParamToNormalized (id, pgm); +#else + float value = pgm; + if (_n_factory_presets > 1) { + value /= (_n_factory_presets - 1.f); + } +#endif + int32 index; _input_param_changes.addParameterData (id, index)->addPoint (sample_off, value, index); _controller->setParamNormalized (id, value);