Add mutexes for the VST3 data caches

Since the restart will always be called from another thread, and when a
plugin asks for a restart during initialization this can quickly lead to
issues.
This commit is contained in:
Robbert van der Helm
2021-01-30 23:26:57 +01:00
parent 27370ab54b
commit 81d401f06a
2 changed files with 94 additions and 56 deletions
+41 -5
View File
@@ -145,11 +145,14 @@ tresult PLUGIN_API Vst3PluginProxyImpl::setProcessing(TBool state) {
// REAPER will repeatedly query the plugin for its bus information on every // REAPER will repeatedly query the plugin for its bus information on every
// processing cycle. Because this really adds up in terms of latency we // processing cycle. Because this really adds up in terms of latency we
// sadly have to deviate from yabridge's principles and implement a cache // sadly have to deviate from yabridge's principles and implement a cache
{
std::lock_guard lock(processing_bus_cache_mutex);
if (state) { if (state) {
processing_bus_cache.emplace(); processing_bus_cache.emplace();
} else { } else {
processing_bus_cache.reset(); processing_bus_cache.reset();
} }
}
return bridge.send_audio_processor_message(YaAudioProcessor::SetProcessing{ return bridge.send_audio_processor_message(YaAudioProcessor::SetProcessing{
.instance_id = instance_id(), .state = state}); .instance_id = instance_id(), .state = state});
@@ -225,24 +228,32 @@ Vst3PluginProxyImpl::getBusCount(Steinberg::Vst::MediaType type,
// issue in REAPER // issue in REAPER
std::tuple<Steinberg::Vst::MediaType, Steinberg::Vst::BusDirection> args{ std::tuple<Steinberg::Vst::MediaType, Steinberg::Vst::BusDirection> args{
type, dir}; type, dir};
{
std::lock_guard lock(processing_bus_cache_mutex);
if (processing_bus_cache) { if (processing_bus_cache) {
if (auto it = processing_bus_cache->bus_count.find(args); if (auto it = processing_bus_cache->bus_count.find(args);
it != processing_bus_cache->bus_count.end()) { it != processing_bus_cache->bus_count.end()) {
const bool log_response = bridge.logger.log_request(true, request); const bool log_response =
bridge.logger.log_request(true, request);
if (log_response) { if (log_response) {
bridge.logger.log_response( bridge.logger.log_response(
true, YaComponent::GetBusCount::Response(it->second), true); true, YaComponent::GetBusCount::Response(it->second),
true);
} }
return it->second; return it->second;
} }
} }
}
const int32 result = bridge.send_audio_processor_message(request); const int32 result = bridge.send_audio_processor_message(request);
{
std::lock_guard lock(processing_bus_cache_mutex);
if (processing_bus_cache) { if (processing_bus_cache) {
processing_bus_cache->bus_count[args] = result; processing_bus_cache->bus_count[args] = result;
} }
}
return result; return result;
} }
@@ -262,12 +273,16 @@ Vst3PluginProxyImpl::getBusInfo(Steinberg::Vst::MediaType type,
// issue in REAPER // issue in REAPER
std::tuple<Steinberg::Vst::MediaType, Steinberg::Vst::BusDirection, int32> std::tuple<Steinberg::Vst::MediaType, Steinberg::Vst::BusDirection, int32>
args{type, dir, index}; args{type, dir, index};
{
std::lock_guard lock(processing_bus_cache_mutex);
if (processing_bus_cache) { if (processing_bus_cache) {
if (auto it = processing_bus_cache->bus_info.find(args); if (auto it = processing_bus_cache->bus_info.find(args);
it != processing_bus_cache->bus_info.end()) { it != processing_bus_cache->bus_info.end()) {
const bool log_response = bridge.logger.log_request(true, request); const bool log_response =
bridge.logger.log_request(true, request);
if (log_response) { if (log_response) {
bridge.logger.log_response(true, bridge.logger.log_response(
true,
YaComponent::GetBusInfo::Response{ YaComponent::GetBusInfo::Response{
.result = Steinberg::kResultOk, .result = Steinberg::kResultOk,
.updated_bus = it->second}, .updated_bus = it->second},
@@ -279,14 +294,19 @@ Vst3PluginProxyImpl::getBusInfo(Steinberg::Vst::MediaType type,
return Steinberg::kResultOk; return Steinberg::kResultOk;
} }
} }
}
const GetBusInfoResponse response = const GetBusInfoResponse response =
bridge.send_audio_processor_message(request); bridge.send_audio_processor_message(request);
bus = response.updated_bus; bus = response.updated_bus;
{
std::lock_guard lock(processing_bus_cache_mutex);
if (processing_bus_cache) { if (processing_bus_cache) {
processing_bus_cache->bus_info[args] = response.updated_bus; processing_bus_cache->bus_info[args] = response.updated_bus;
} }
}
return response.result; return response.result;
} }
@@ -440,6 +460,8 @@ int32 PLUGIN_API Vst3PluginProxyImpl::getParameterCount() {
// We'll cache this information to work around an issue in REAPER, see // We'll cache this information to work around an issue in REAPER, see
// `parameter_info_cache` // `parameter_info_cache`
{
std::lock_guard lock(parameter_info_cache_mutex);
if (parameter_info_cache.parameter_count) { if (parameter_info_cache.parameter_count) {
const bool log_response = bridge.logger.log_request(true, request); const bool log_response = bridge.logger.log_request(true, request);
if (log_response) { if (log_response) {
@@ -452,10 +474,14 @@ int32 PLUGIN_API Vst3PluginProxyImpl::getParameterCount() {
return *parameter_info_cache.parameter_count; return *parameter_info_cache.parameter_count;
} }
}
const int32 result = bridge.send_message(request); const int32 result = bridge.send_message(request);
{
std::lock_guard lock(parameter_info_cache_mutex);
parameter_info_cache.parameter_count = result; parameter_info_cache.parameter_count = result;
}
return result; return result;
} }
@@ -468,6 +494,8 @@ tresult PLUGIN_API Vst3PluginProxyImpl::getParameterInfo(
// We'll cache this information to work around an issue in REAPER, see // We'll cache this information to work around an issue in REAPER, see
// `parameter_info_cache` // `parameter_info_cache`
{
std::lock_guard lock(parameter_info_cache_mutex);
if (auto it = parameter_info_cache.parameter_info.find(paramIndex); if (auto it = parameter_info_cache.parameter_info.find(paramIndex);
it != parameter_info_cache.parameter_info.end()) { it != parameter_info_cache.parameter_info.end()) {
const bool log_response = bridge.logger.log_request(true, request); const bool log_response = bridge.logger.log_request(true, request);
@@ -475,7 +503,8 @@ tresult PLUGIN_API Vst3PluginProxyImpl::getParameterInfo(
bridge.logger.log_response( bridge.logger.log_response(
true, true,
YaEditController::GetParameterInfo::Response{ YaEditController::GetParameterInfo::Response{
.result = Steinberg::kResultOk, .updated_info = it->second}, .result = Steinberg::kResultOk,
.updated_info = it->second},
true); true);
} }
@@ -483,11 +512,16 @@ tresult PLUGIN_API Vst3PluginProxyImpl::getParameterInfo(
return Steinberg::kResultOk; return Steinberg::kResultOk;
} }
}
const GetParameterInfoResponse response = bridge.send_message(request); const GetParameterInfoResponse response = bridge.send_message(request);
info = response.updated_info; info = response.updated_info;
{
std::lock_guard lock(parameter_info_cache_mutex);
parameter_info_cache.parameter_info[paramIndex] = response.updated_info; parameter_info_cache.parameter_info[paramIndex] = response.updated_info;
}
return response.result; return response.result;
} }
@@ -1158,11 +1192,13 @@ tresult PLUGIN_API Vst3PluginProxyImpl::getXmlRepresentationStream(
} }
void Vst3PluginProxyImpl::clear_bus_cache() { void Vst3PluginProxyImpl::clear_bus_cache() {
std::lock_guard lock(processing_bus_cache_mutex);
if (processing_bus_cache) { if (processing_bus_cache) {
processing_bus_cache.emplace(); processing_bus_cache.emplace();
} }
} }
void Vst3PluginProxyImpl::clear_parameter_cache() { void Vst3PluginProxyImpl::clear_parameter_cache() {
std::lock_guard lock(parameter_info_cache_mutex);
parameter_info_cache = ParameterInfoCache{}; parameter_info_cache = ParameterInfoCache{};
} }
@@ -487,6 +487,7 @@ class Vst3PluginProxyImpl : public Vst3PluginProxy {
* does that. * does that.
*/ */
std::optional<BusInfoCache> processing_bus_cache; std::optional<BusInfoCache> processing_bus_cache;
std::mutex processing_bus_cache_mutex;
/** /**
* A cache for `IEditController::getParameterCount()` and * A cache for `IEditController::getParameterCount()` and
@@ -513,4 +514,5 @@ class Vst3PluginProxyImpl : public Vst3PluginProxy {
* information four times per second. * information four times per second.
*/ */
ParameterInfoCache parameter_info_cache; ParameterInfoCache parameter_info_cache;
std::mutex parameter_info_cache_mutex;
}; };