VST3: work around plugins that do not heed ContextInfo::kSendCount

see also c5618f01d6
This commit is contained in:
Robin Gareus 2024-10-01 22:58:44 +02:00
parent 07c79ce92c
commit adc9d9e0af
No known key found for this signature in database
GPG key ID: A090BCE02CF57F04
6 changed files with 27 additions and 9 deletions

View file

@ -553,7 +553,7 @@ public:
std::shared_ptr<AutomationControl> mapped_control (enum WellKnownCtrl, uint32_t band = 0) const; std::shared_ptr<AutomationControl> mapped_control (enum WellKnownCtrl, uint32_t band = 0) const;
std::shared_ptr<ReadOnlyControl> mapped_output (enum WellKnownData) const; std::shared_ptr<ReadOnlyControl> mapped_output (enum WellKnownData) const;
std::shared_ptr<AutomationControl> send_level_controllable (uint32_t n) const; std::shared_ptr<AutomationControl> send_level_controllable (uint32_t n, bool locked = false) const;
std::shared_ptr<AutomationControl> send_enable_controllable (uint32_t n) const; std::shared_ptr<AutomationControl> send_enable_controllable (uint32_t n) const;
std::shared_ptr<AutomationControl> send_pan_azimuth_controllable (uint32_t n) const; std::shared_ptr<AutomationControl> send_pan_azimuth_controllable (uint32_t n) const;
std::shared_ptr<AutomationControl> send_pan_azimuth_enable_controllable (uint32_t n) const; std::shared_ptr<AutomationControl> send_pan_azimuth_enable_controllable (uint32_t n) const;

View file

@ -158,7 +158,7 @@ class LIBARDOUR_API Stripable : public SessionObject,
* In Ardour, these are user-created sends that connect to user-created * In Ardour, these are user-created sends that connect to user-created
* Aux busses. * Aux busses.
*/ */
virtual std::shared_ptr<AutomationControl> send_level_controllable (uint32_t n) const = 0; virtual std::shared_ptr<AutomationControl> send_level_controllable (uint32_t n, bool locked = false) const = 0;
virtual std::shared_ptr<AutomationControl> send_enable_controllable (uint32_t n) const = 0; virtual std::shared_ptr<AutomationControl> send_enable_controllable (uint32_t n) const = 0;
virtual std::shared_ptr<AutomationControl> send_pan_azimuth_controllable (uint32_t n) const = 0; virtual std::shared_ptr<AutomationControl> send_pan_azimuth_controllable (uint32_t n) const = 0;
virtual std::shared_ptr<AutomationControl> send_pan_azimuth_enable_controllable (uint32_t n) const = 0; virtual std::shared_ptr<AutomationControl> send_pan_azimuth_enable_controllable (uint32_t n) const = 0;

View file

@ -134,7 +134,7 @@ class LIBARDOUR_API VCA : public Stripable,
uint32_t eq_band_cnt () const { return 0; } uint32_t eq_band_cnt () const { return 0; }
std::string eq_band_name (uint32_t) const { return std::string(); } std::string eq_band_name (uint32_t) const { return std::string(); }
std::shared_ptr<AutomationControl> send_level_controllable (uint32_t n) const { return std::shared_ptr<AutomationControl>(); } std::shared_ptr<AutomationControl> send_level_controllable (uint32_t n, bool locked = false) const { return std::shared_ptr<AutomationControl>(); }
std::shared_ptr<AutomationControl> send_enable_controllable (uint32_t n) const { return std::shared_ptr<AutomationControl>(); } std::shared_ptr<AutomationControl> send_enable_controllable (uint32_t n) const { return std::shared_ptr<AutomationControl>(); }
std::shared_ptr<AutomationControl> send_pan_azimuth_controllable (uint32_t n) const { return std::shared_ptr<AutomationControl>(); } std::shared_ptr<AutomationControl> send_pan_azimuth_controllable (uint32_t n) const { return std::shared_ptr<AutomationControl>(); }
std::shared_ptr<AutomationControl> send_pan_azimuth_enable_controllable (uint32_t n) const { return std::shared_ptr<AutomationControl>(); } std::shared_ptr<AutomationControl> send_pan_azimuth_enable_controllable (uint32_t n) const { return std::shared_ptr<AutomationControl>(); }

View file

@ -359,6 +359,10 @@ private:
bool _no_kMono; bool _no_kMono;
/* work around yabridge threading */ /* work around yabridge threading */
bool _restart_component_is_synced; bool _restart_component_is_synced;
/* work around PSL calls during set_owner,
* while the route holds a processor lock
*/
std::atomic<bool> _in_set_owner;
}; };
} // namespace Steinberg } // namespace Steinberg

View file

@ -5927,8 +5927,15 @@ Route::send_pan_azimuth_controllable (uint32_t n) const
} }
std::shared_ptr<AutomationControl> std::shared_ptr<AutomationControl>
Route::send_level_controllable (uint32_t n) const Route::send_level_controllable (uint32_t n, bool locked) const
{ {
if (locked) {
/* calling thread has a WriterLock (_processor_lock)
* we cannot call nth_send()
*/
return std::shared_ptr<AutomationControl>();
}
std::shared_ptr<Send> s = std::dynamic_pointer_cast<Send>(nth_send (n)); std::shared_ptr<Send> s = std::dynamic_pointer_cast<Send>(nth_send (n));
if (s) { if (s) {
return s->gain_control (); return s->gain_control ();

View file

@ -1195,6 +1195,7 @@ VST3PI::VST3PI (std::shared_ptr<ARDOUR::VST3PluginModule> m, std::string unique_
, _rpc_queue (RouteProcessorChange::NoProcessorChange, false) , _rpc_queue (RouteProcessorChange::NoProcessorChange, false)
, _no_kMono (false) , _no_kMono (false)
, _restart_component_is_synced (false) , _restart_component_is_synced (false)
, _in_set_owner (false)
{ {
using namespace std; using namespace std;
IPluginFactory* factory = m->factory (); IPluginFactory* factory = m->factory ();
@ -1835,9 +1836,13 @@ VST3PI::set_owner (SessionObject* o)
return; return;
} }
_in_set_owner.store (true);
if (!setup_psl_info_handler ()) { if (!setup_psl_info_handler ()) {
setup_info_listener (); setup_info_listener ();
} }
_in_set_owner.store (false);
} }
void void
@ -2809,7 +2814,7 @@ VST3PI::automation_state_changed (uint32_t port, AutoState s, std::weak_ptr<Auto
/* ****************************************************************************/ /* ****************************************************************************/
static std::shared_ptr<AutomationControl> static std::shared_ptr<AutomationControl>
lookup_ac (SessionObject* o, FIDString id) lookup_ac (SessionObject* o, FIDString id, bool locked = false)
{ {
Stripable* s = dynamic_cast<Stripable*> (o); Stripable* s = dynamic_cast<Stripable*> (o);
if (!s) { if (!s) {
@ -2842,8 +2847,8 @@ lookup_ac (SessionObject* o, FIDString id)
* recurive locks (deadlock, or double unlock crash). * recurive locks (deadlock, or double unlock crash).
*/ */
int send_id = atoi (id + strlen (ContextInfo::kSendLevel)); int send_id = atoi (id + strlen (ContextInfo::kSendLevel));
if (s->send_enable_controllable (send_id)) { if (send_id >=0 && s->send_enable_controllable (send_id)) {
return s->send_level_controllable (send_id); return s->send_level_controllable (send_id, locked);
} }
#endif #endif
} }
@ -2967,6 +2972,7 @@ VST3PI::getContextInfoValue (double& value, FIDString id)
value = 2.0; // Config->get_max_gain(); value = 2.0; // Config->get_max_gain();
#ifdef MIXBUS #ifdef MIXBUS
if (s->send_enable_controllable (0)) { if (s->send_enable_controllable (0)) {
assert (s->send_level_controllable (0));
value = s->send_level_controllable (0)->upper (); // pow (10.0, .05 * 15.0); value = s->send_level_controllable (0)->upper (); // pow (10.0, .05 * 15.0);
} }
#endif #endif
@ -2983,11 +2989,12 @@ VST3PI::getContextInfoValue (double& value, FIDString id)
value = 0.5; // center value = 0.5; // center
} }
} else if (0 == strncmp (id, ContextInfo::kSendLevel, strlen (ContextInfo::kSendLevel))) { } else if (0 == strncmp (id, ContextInfo::kSendLevel, strlen (ContextInfo::kSendLevel))) {
std::shared_ptr<AutomationControl> ac = lookup_ac (_owner, id); std::shared_ptr<AutomationControl> ac = lookup_ac (_owner, id, _in_set_owner.load ());
if (ac) { if (ac) {
value = ac->get_value (); // gain cofficient value = ac->get_value (); // gain cofficient
psl_subscribe_to (ac, id); psl_subscribe_to (ac, id);
} else { } else {
value = 0;
DEBUG_TRACE (DEBUG::VST3Callbacks, string_compose ("VST3PI::getContextInfoValue<double> invalid AC %1\n", id)); DEBUG_TRACE (DEBUG::VST3Callbacks, string_compose ("VST3PI::getContextInfoValue<double> invalid AC %1\n", id));
return kInvalidArgument; // send index out of bounds return kInvalidArgument; // send index out of bounds
} }
@ -3023,7 +3030,7 @@ VST3PI::setContextInfoValue (FIDString id, double value)
ac->set_value (ac->interface_to_internal (value, true), PBD::Controllable::NoGroup); ac->set_value (ac->interface_to_internal (value, true), PBD::Controllable::NoGroup);
} }
} else if (0 == strncmp (id, ContextInfo::kSendLevel, strlen (ContextInfo::kSendLevel))) { } else if (0 == strncmp (id, ContextInfo::kSendLevel, strlen (ContextInfo::kSendLevel))) {
std::shared_ptr<AutomationControl> ac = lookup_ac (_owner, id); std::shared_ptr<AutomationControl> ac = lookup_ac (_owner, id, _in_set_owner.load ());
if (ac) { if (ac) {
ac->set_value (value, Controllable::NoGroup); ac->set_value (value, Controllable::NoGroup);
} else { } else {