Reword caching to prefetching

Since that makes it much clearer what we're actually doing. With old
`cache_time_info` was actually caching the response, but now we're
querying it before the plugin has even requested the information.
This commit is contained in:
Robbert van der Helm
2021-04-29 01:07:14 +02:00
parent c82eb35243
commit 6f6e6c5b94
5 changed files with 26 additions and 24 deletions
+13 -11
View File
@@ -10,17 +10,19 @@ Versioning](https://semver.org/spec/v2.0.0.html).
### Added ### Added
- During VST2 audio processing calls, yabridge will now immediately send the - During VST2 audio processing calls, yabridge will now prefetch the current
current transport information along with the audio buffers. This lets us cache transport information and send that to the Wine plugin host along with the
this information during the processing call, which significantly reduce the audio buffers. This lets us cache this information during the processing call,
overhead of bridging VST2 plugins by avoiding one otherwise mandatory back and which significantly reduces the overhead of bridging VST2 plugins by avoiding
forth function call between yabridge's plugin and the Wine plugin host. This one otherwise mandatory back and forth function call between yabridge's plugin
has an even greater impact on plugins like _SWAM Cello_ that request this and the Wine plugin host. This has an even greater impact on plugins like
information repeatedly for every sample they process. Previously yabridge had _SWAM Cello_ that request this information repeatedly over the course of a
a `cache_time_info` compatibility option to mitigate the performance hit for single audio processing cycle. Previously yabridge had a `cache_time_info`
those plugins, but this new caching behaviour supercedes that. compatibility option to mitigate the performance hit for those plugins, but
- Similarly, yabridge will also cache the current process level during audio this new caching behaviour supercedes that.
processing to reduce bridging overhead for plugins that use this. - Similarly, yabridge will also prefetch the current process level during audio
processing to reduce bridging overhead for plugins that use this, like the
_Meldaproduction_ plugins.
- We now always force the CPU's flush-to-zero flag to be set when processing - We now always force the CPU's flush-to-zero flag to be set when processing
audio. Most plugins will already do this themselves, but plugins like _Kush audio. Most plugins will already do this themselves, but plugins like _Kush
Audio REDDI_ and _Expressive E Noisy_ that don't will otherwise suffer from Audio REDDI_ and _Expressive E Noisy_ that don't will otherwise suffer from
+5 -5
View File
@@ -556,16 +556,16 @@ struct AudioBuffers {
int sample_frames; int sample_frames;
/** /**
* We'll send the current transport information as part of an audio * We'll prefetch the current transport information as part of handling an
* processing call. This lets us a void an unnecessary callback (or in some * audio processing call. This lets us a void an unnecessary callback (or in
* cases, more than one) during every processing cycle. * some cases, more than one) during every processing cycle.
*/ */
std::optional<VstTimeInfo> current_time_info; std::optional<VstTimeInfo> current_time_info;
/** /**
* Some plugins will also ask for the current process level during audio * Some plugins will also ask for the current process level during audio
* processing. To prevent unnecessary expensive callbacks, we'll send this * processing. To prevent unnecessary expensive callbacks there, we'll
* information along with the processing call. * prefetch this information as well.
*/ */
int current_process_level; int current_process_level;
+2 -2
View File
@@ -568,8 +568,8 @@ void Vst2PluginBridge::do_process(T** inputs, T** outputs, int sample_frames) {
current_time_info = *returned_time_info; current_time_info = *returned_time_info;
} }
// Some plugisn also ask for the current process level, so we'll cache that // Some plugisn also ask for the current process level, so we'll prefetch
// information as well // that information as well
const int current_process_level = static_cast<int>(host_callback_function( const int current_process_level = static_cast<int>(host_callback_function(
&plugin, audioMasterGetCurrentProcessLevel, 0, 0, nullptr, 0.0)); &plugin, audioMasterGetCurrentProcessLevel, 0, 0, nullptr, 0.0));
if (returned_time_info) { if (returned_time_info) {
+3 -3
View File
@@ -188,7 +188,7 @@ Vst2Bridge::Vst2Bridge(MainContext& main_context,
[&](AudioBuffers request, std::vector<uint8_t>& buffer) { [&](AudioBuffers request, std::vector<uint8_t>& buffer) {
// Since the value cannot change during this processing cycle, // Since the value cannot change during this processing cycle,
// we'll send the current transport information as part of the // we'll send the current transport information as part of the
// request so we cache it to avoid unnecessary callbacks from // request so we prefetch it to avoid unnecessary callbacks from
// the audio thread // the audio thread
std::optional<decltype(time_info_cache)::Guard> std::optional<decltype(time_info_cache)::Guard>
time_info_cache_guard = time_info_cache_guard =
@@ -197,8 +197,8 @@ Vst2Bridge::Vst2Bridge(MainContext& main_context,
*request.current_time_info)) *request.current_time_info))
: std::nullopt; : std::nullopt;
// We'll also cache the process level, since some plugins will // We'll also prefetch the process level, since some plugins
// ask for this during every processing cycle // will ask for this during every processing cycle
decltype(process_level_cache)::Guard process_level_cache_guard = decltype(process_level_cache)::Guard process_level_cache_guard =
process_level_cache.set(request.current_process_level); process_level_cache.set(request.current_process_level);
+3 -3
View File
@@ -114,8 +114,8 @@ class Vst2Bridge : public HostBridge {
* We'll store the last transport information obtained from the host as a * We'll store the last transport information obtained from the host as a
* result of `audioMasterGetTime()` here so we can return a pointer to it if * result of `audioMasterGetTime()` here so we can return a pointer to it if
* the request was successful. To prevent unnecessary back and forth * the request was successful. To prevent unnecessary back and forth
* communication, we'll send a copy of the current transport information to * communication, we'll prefetch the current transport information in the
* the plugin as part of the audio processing call. * plugin as part of the audio processing call.
* *
* @see cached_time_info * @see cached_time_info
*/ */
@@ -131,7 +131,7 @@ class Vst2Bridge : public HostBridge {
/** /**
* Some plugins will also ask for the current process level during audio * Some plugins will also ask for the current process level during audio
* processing, so we'll also cache that to prevent expensive callbacks. * processing, so we'll also prefetch that to prevent expensive callbacks.
*/ */
ScopedValueCache<int> process_level_cache; ScopedValueCache<int> process_level_cache;