From 3722b8a94f3818f5b8a7e8ce2d7de806def835fb Mon Sep 17 00:00:00 2001 From: Robin Gareus Date: Tue, 2 Mar 2021 03:21:08 +0100 Subject: [PATCH] VST3: work around plugins with missing controller state If a plugin implements Vst::IComponent::set_state() but does not implement Vst::IEditController::setComponentState() nor dedicated get/setState interface for the IEditController, querying the parameters using Vst::IEditController::getParamNormalized() returns values that do reflect the restored state. In this case the host needs to save/restore all control-parameters, and ignore values reported by ::getParamNormalized(). This fixes a state save/restore issue with softube.vst3, however vstpresets are still broken: the GUI (IComponent) is updated, however the controller isn't. --- libs/ardour/vst3_plugin.cc | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/libs/ardour/vst3_plugin.cc b/libs/ardour/vst3_plugin.cc index 8813d56f1f..05f3961b33 100644 --- a/libs/ardour/vst3_plugin.cc +++ b/libs/ardour/vst3_plugin.cc @@ -1754,10 +1754,10 @@ VST3PI::synchronize_states () std::cerr << "Failed to synchronize VST3 component <> controller state\n"; stream.hexdump (0); #endif - return false; } + return res == kResultOk; } - return true; + return false; } void @@ -2259,6 +2259,7 @@ VST3PI::load_state (RAMStream& stream) } bool rv = true; + bool synced = false; /* parse chunks */ for (ChunkEntryVector::const_iterator i = entries.begin (); i != entries.end (); ++i) { @@ -2274,6 +2275,10 @@ VST3PI::load_state (RAMStream& stream) s.rewind (); tresult re2 = _controller->setComponentState (&s); + if (re2 == kResultOk) { + synced = true; + } + if (!(re2 == kResultOk || re2 == kNotImplemented || res == kResultOk || res == kNotImplemented)) { DEBUG_TRACE (DEBUG::VST3Config, "VST3PI::load_state: failed to restore component state\n"); rv = false; @@ -2281,6 +2286,10 @@ VST3PI::load_state (RAMStream& stream) } else if (is_equal_ID (i->_id, Vst::getChunkID (Vst::kControllerState))) { stream.seek (i->_offset, IBStream::kIBSeekSet, &seek_result); tresult res = _controller->setState (&stream); + if (res == kResultOk) { + synced = true; + } + if (!(res == kResultOk || res == kNotImplemented)) { DEBUG_TRACE (DEBUG::VST3Config, "VST3PI::load_state: failed to restore controller state\n"); rv = false; @@ -2302,8 +2311,11 @@ VST3PI::load_state (RAMStream& stream) DEBUG_TRACE (DEBUG::VST3Config, "VST3PI::load_state: ignored unsupported state chunk.\n"); } } + if (rv && !synced) { + synced = synchronize_states (); + } - if (rv) { + if (rv && synced) { update_shadow_data (); } return rv;