From b6f96fc9201016caecbbf68a1308f05cd8ea4677 Mon Sep 17 00:00:00 2001 From: Robbert van der Helm Date: Thu, 6 May 2021 18:32:46 +0200 Subject: [PATCH] Cache IAudioProcessor::canProcessSampleSize() --- CHANGELOG.md | 5 +++ .../bridges/vst3-impls/plugin-proxy.cpp | 35 ++++++++++++++++--- src/plugin/bridges/vst3-impls/plugin-proxy.h | 5 +++ 3 files changed, 41 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1615f818..c1ac4363 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,6 +13,11 @@ Versioning](https://semver.org/spec/v2.0.0.html). - Added a timed cache for the `IPluginView::canResize()` VST3 function, so value will be remembered during an active resize. This makes resizing VST3 plugin editor windows more responsive. +- Add a cache for VST3 function calls where the host asks the plugin whether it + can process 32-bit or 64-bit floating point audio. Some hosts will call this + function every processing cycle even though the value doesn't change. Caching + this can significantly reduce the overhead of bridging VST3 plugins under + those hosts. ## [3.2.0] - 2021-05-03 diff --git a/src/plugin/bridges/vst3-impls/plugin-proxy.cpp b/src/plugin/bridges/vst3-impls/plugin-proxy.cpp index 3438299b..14e81fa8 100644 --- a/src/plugin/bridges/vst3-impls/plugin-proxy.cpp +++ b/src/plugin/bridges/vst3-impls/plugin-proxy.cpp @@ -139,10 +139,37 @@ tresult PLUGIN_API Vst3PluginProxyImpl::getBusArrangement( tresult PLUGIN_API Vst3PluginProxyImpl::canProcessSampleSize(int32 symbolicSampleSize) { - return bridge.send_audio_processor_message( - YaAudioProcessor::CanProcessSampleSize{ - .instance_id = instance_id(), - .symbolic_sample_size = symbolicSampleSize}); + const auto request = YaAudioProcessor::CanProcessSampleSize{ + .instance_id = instance_id(), + .symbolic_sample_size = symbolicSampleSize}; + + { + std::lock_guard lock(function_result_cache_mutex); + if (auto it = function_result_cache.can_process_sample_size.find( + symbolicSampleSize); + it != function_result_cache.can_process_sample_size.end()) { + const bool log_response = bridge.logger.log_request(true, request); + if (log_response) { + bridge.logger.log_response( + true, + YaAudioProcessor::CanProcessSampleSize::Response( + it->second), + true); + } + + return *function_result_cache.parameter_count; + } + } + + const tresult result = bridge.send_audio_processor_message(request); + + { + std::lock_guard lock(function_result_cache_mutex); + function_result_cache.can_process_sample_size[symbolicSampleSize] = + result; + } + + return result; } uint32 PLUGIN_API Vst3PluginProxyImpl::getLatencySamples() { diff --git a/src/plugin/bridges/vst3-impls/plugin-proxy.h b/src/plugin/bridges/vst3-impls/plugin-proxy.h index df9dbc8a..41a69e6f 100644 --- a/src/plugin/bridges/vst3-impls/plugin-proxy.h +++ b/src/plugin/bridges/vst3-impls/plugin-proxy.h @@ -531,6 +531,11 @@ class Vst3PluginProxyImpl : public Vst3PluginProxy { * @see function_result_cache */ struct FunctionResultCache { + /** + * Memoizes `IAudioProcessor::canProcessSampleSize()`, since some hosts + * call this every processing cycle. + */ + std::map can_process_sample_size; /** * Memoizes `IEditController::getParameterCount()`. */